Merge lp:~cemil-azizoglu/mir/mir-on-x into lp:mir
- mir-on-x
- Merge into development-branch
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Cemil Azizoglu | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | 2769 | ||||
Proposed branch: | lp:~cemil-azizoglu/mir/mir-on-x | ||||
Merge into: | lp:mir | ||||
Prerequisite: | lp:~cemil-azizoglu/mir/use-options-on-probing | ||||
Diff against target: |
3224 lines (+2433/-85) 56 files modified
CMakeLists.txt (+6/-3) src/platforms/CMakeLists.txt (+2/-2) src/platforms/mesa/server/CMakeLists.txt (+3/-0) src/platforms/mesa/server/common/buffer_allocator.cpp (+105/-18) src/platforms/mesa/server/common/buffer_allocator.h (+9/-1) src/platforms/mesa/server/common/display_helpers.cpp (+28/-17) src/platforms/mesa/server/common/display_helpers.h (+8/-1) src/platforms/mesa/server/common/ipc_operations.cpp (+4/-5) src/platforms/mesa/server/common/ipc_operations.h (+2/-2) src/platforms/mesa/server/kms/guest_platform.cpp (+2/-2) src/platforms/mesa/server/kms/platform.cpp (+5/-4) src/platforms/mesa/server/x11/CMakeLists.txt (+61/-0) src/platforms/mesa/server/x11/display.cpp (+274/-0) src/platforms/mesa/server/x11/display.h (+131/-0) src/platforms/mesa/server/x11/display_buffer.cpp (+68/-0) src/platforms/mesa/server/x11/display_buffer.h (+59/-0) src/platforms/mesa/server/x11/display_configuration.cpp (+63/-0) src/platforms/mesa/server/x11/display_configuration.h (+52/-0) src/platforms/mesa/server/x11/display_group.cpp (+42/-0) src/platforms/mesa/server/x11/display_group.h (+51/-0) src/platforms/mesa/server/x11/gl_context.cpp (+45/-0) src/platforms/mesa/server/x11/gl_context.h (+52/-0) src/platforms/mesa/server/x11/input/dispatchable.cpp (+132/-0) src/platforms/mesa/server/x11/input/dispatchable.h (+52/-0) src/platforms/mesa/server/x11/input/input.cpp (+60/-0) src/platforms/mesa/server/x11/input/input_device.cpp (+54/-0) src/platforms/mesa/server/x11/input/input_device.h (+66/-0) src/platforms/mesa/server/x11/input/input_platform.cpp (+51/-0) src/platforms/mesa/server/x11/input/input_platform.h (+60/-0) src/platforms/mesa/server/x11/platform.cpp (+135/-0) src/platforms/mesa/server/x11/platform.h (+61/-0) src/platforms/mesa/server/x11/symbols.map (+18/-0) src/platforms/mesa/server/x11/xserver_connection.h (+47/-0) tests/CMakeLists.txt (+4/-0) tests/acceptance-tests/test_client_library.cpp (+10/-10) tests/include/mir/test/doubles/mock_input_sink.h (+44/-0) tests/include/mir/test/doubles/mock_x11.h (+78/-0) tests/mir_test_doubles/CMakeLists.txt (+6/-0) tests/mir_test_doubles/mock_x11.cpp (+133/-0) tests/mir_test_doubles/platform_factory.cpp (+9/-1) tests/mir_test_doubles/stub_buffer.cpp (+3/-3) tests/mir_test_framework/stubbed_graphics_platform.cpp (+2/-2) tests/unit-tests/CMakeLists.txt (+8/-2) tests/unit-tests/client/CMakeLists.txt (+1/-1) tests/unit-tests/graphics/CMakeLists.txt (+10/-5) tests/unit-tests/graphics/mesa/CMakeLists.txt (+4/-0) tests/unit-tests/graphics/mesa/common/CMakeLists.txt (+0/-2) tests/unit-tests/graphics/mesa/common/test_drm_helper.cpp (+1/-1) tests/unit-tests/graphics/mesa/kms/CMakeLists.txt (+2/-0) tests/unit-tests/graphics/mesa/kms/test_buffer_allocator.cpp (+3/-2) tests/unit-tests/graphics/mesa/kms/test_gbm_buffer.cpp (+1/-1) tests/unit-tests/graphics/mesa/x11/CMakeLists.txt (+6/-0) tests/unit-tests/graphics/mesa/x11/test_display.cpp (+101/-0) tests/unit-tests/graphics/mesa/x11/test_platform.cpp (+125/-0) tests/unit-tests/input/CMakeLists.txt (+6/-0) tests/unit-tests/input/test_x11_dispatchable.cpp (+68/-0) |
||||
To merge this branch: | bzr merge lp:~cemil-azizoglu/mir/mir-on-x | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Kevin DuBois (community) | Approve | ||
Alan Griffiths | Approve | ||
Alexandros Frantzis (community) | Approve | ||
Robert Carr (community) | Approve | ||
Chris Halse Rogers | Approve | ||
Cemil Azizoglu | Pending | ||
Review via email: mp+265163@code.launchpad.net |
This proposal supersedes a proposal from 2015-07-09.
Commit message
Add X as a platform so Mir server and clients can be run under X11.
Description of the change
Add X as a platform so Mir server and clients can be run under X11.
To run the server-side, use (no need to be root):
bin/mir_demo_server --platform-
mesa-x11.so.3
Running a client is exactly the same as Mesa (except you don't need to be root), as mir-on-x is a server-side only notion.
There is still a lot of work to do depending on how far we want to go. Since this platform is mostly intended for developers (as opposed to end-users), we can refine as we go.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:2673
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : Posted in a previous version of this proposal | # |
Some high level first impressions:
~~~~~~~~~
The automatic module detection doesn't work correctly. In case of a priority tie, the first module found (in filesystem order) is selected. If that module is mesa-kms then mesa-x11 can never be loaded unless forced with the platform-
~~~~~~~~~
I can't get any output on intel for EGL clients and only the first frame for software clients (I think these are known issues?).
~~~~~~~~~
196 + bool const use_dma_
It's better to use an enum for readability, since true/false values are very uninformative, e.g.:
return std::make_
Compare the existing second (enum) to the new third (bool) option.
~~~~~~~~~
253 + return mir::Fd{
We should dup() this fd to maintain the interface (i.e., that authenticated_fd() returns a new, independent fd). Ideally we would change the calling code to properly use mir::Fds, but that is beyond the scope of this MP.
~~~~~~~~~
333 + DRMHelper(bool const use_render_node)
Similarly, better to use an enum instead of a bool.
~~~~~~~~~
353 -mgm::IpcOperat
355 +mgm::IpcOperat
...
364 + if (!authenticate)
365 + BOOST_THROW_
366 + std::runtime_
We should let the DRMAuthenticator succeed or fail here on its own, no need for changing the IpcOperations code at all. I think the proposed version of DRMHelper will fail in the right way (i.e., throw for auth_magic(), succeed for auth_fd()).
~~~~~~~~~
394 + if (!authenticate)
395 + {
396 + auto package = std::make_
397 + package-
398 + return package;
399 + }
400 + return std::make_
The two paths are functionally equivalent except 1. the dup() in the first path and 2. the first path leaks fds. As suggested earlier, it's better to dup inside authenticated_fd(), and by doing so we wouldn't need to change the code here at all.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:2674
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
> Some high level first impressions:
>
> ~~~~~~~~~
>
> The automatic module detection doesn't work correctly. In case of a priority
> tie, the first module found (in filesystem order) is selected. If that module
> is mesa-kms then mesa-x11 can never be loaded unless forced with the platform-
> graphics-lib option. We need to change mesa-kms and/or mesa-x11 to report
> different priorities depending on the environment.
The obvious thing to do here would be to make mesa-kms try to claim drm master in probe(). That fails when running under X11 (or not running with root), and mesa-kms will fail if it can't claim master anyway.
Apart from what Alexandros has pointed out, I think it's likely that you should be handling md::FdEvent::error in your Dispatchable:
Chris Halse Rogers (raof) : Posted in a previous version of this proposal | # |
Alan Griffiths (alan-griffiths) wrote : Posted in a previous version of this proposal | # |
It looks like there is enough useful feedback without me looking any deeper.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
Thanks for the suggestions. Should all be fixed now.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> Thanks for the suggestions. Should all be fixed now.
- Except for the fd_events::error which I've yet to do.
- Also running "sudo bin/mir_demo_server --vt 3" from an xterm doesn't seem to be working. It errs out saying "unrecognized option 'vt'".
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2678
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
> > Thanks for the suggestions. Should all be fixed now.
>
> - Except for the fd_events::error which I've yet to do.
> - Also running "sudo bin/mir_demo_server --vt 3" from an xterm doesn't seem to
> be working. It errs out saying "unrecognized option 'vt'".
Yeah. This is because the X server has claimed DRM master, and so the mesa-kms probe detects that it can't claim master and bails.
We've talked before about loading *all* the platform modules, presenting all their options, and then having platform-specific options imply the use of that platform. That would fix this.
As I don't try to run mir from X this doesn't bother me :)
Chris Halse Rogers (raof) wrote : Posted in a previous version of this proposal | # |
Otherwise, apart from handling the md::FdEvent::error case, looks good.
Non-blocking nits:
233 +enum class DMABufExtension
234 +{
235 + use,
236 + do_not_use
237 +};
I think this would be clearer as
enum class BufferImportMethod
{
gbm_
dma_buf
};
Or similar; it's more descriptive of what it selects, and allows us to extend the import method in an obvious way if we need to in future.
Nit:
941 + if (!eglMakeCurren
942 + BOOST_THROW_
It's not really a logic error, is it? I'd expect this to be a runtime_error. For bonus marks, I guess, it could be an EGLError : public std::runtime_error and automatically slurp up the value of eglGetError().
1970 +extern "C" mg::PlatformPri
1971 +{
1972 + auto dpy = XOpenDisplay(NULL);
1973 + if (dpy)
1974 + {
1975 + XCloseDisplay(dpy);
1976 +
1977 + auto udev = std::make_
1978 + auto drm = std::make_
1979 +
1980 + try {
1981 + drm->setup(udev);
1982 + drm->set_master();
1983 + }
1984 + catch(...)
1985 + {
1986 + return mg::PlatformPri
1987 + }
1988 +
1989 + drm->drop_master();
1990 + }
1991 + return mg::PlatformPri
1992 +}
This is fine. It'd also be correct to return mg::PlatformPri
2809 +TEST_F(
I don't think this is testing anything useful, and is going to be one of those tests that we update every time we touch the relevant code. I'd prefer it if this test wasn't there.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2679
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : Posted in a previous version of this proposal | # |
> 941 + if (!eglMakeCurren
> 942 + BOOST_THROW_
> It's not really a logic error, is it? I'd expect this to be a runtime_error.
> For bonus marks, I guess, it could be an EGLError : public std::runtime_error
> and automatically slurp up the value of eglGetError().
+1, but note we already have an egl_error we can use (see src/include/
2878 +// fake_devices.
Not needed.
2900 + try
2901 + {
2902 + auto platform = create_platform();
2903 + } catch(...)
2904 + {
2905 + return;
2906 + }
2907 +
2908 + FAIL() << "Expected an exception to be thrown.";
... and elsewhere.
GMock has a construct to express this:
EXPECT_THROW({ create_platform(); }, std::exception); // or use a more specific exception type if applicable
Nit:
635 + EGLint egl_major, egl_minor;
636 + EGLConfig config;
637 + EGLint num_configs;
638 + EGLint vid;
639 + Window root;
640 + XVisualInfo *visInfo, visTemplate;
641 + XSetWindowAttri
642 + int num_visuals;
643 + unsigned long mask;
644 + char const * const title = "Mir On X";
I guess this is based on some C code. In C++, it has proved easier to read to just declare each variable when it's created.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2683
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2686
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:2691
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
partial review so far:
needs fixings:
indentation is a bit awry, some places have tabs
http://
185 + int prime_fd;
Handling of this fd isn't exception-safe (eg, if l177 threw), using mir::Fd would help.
611 +mgx::Display:
some of the resources in this constructor are also not exception safe. (eg, if eglCreateContext threw some of the resources (like win) might leak)
145-150 c-style casts
http://
126 + if (buffer_
Switching on this enum in the buffer type suggests to me that the mgm::Buffer should have two different implementations based on the mapping method, or that there's mgm::BufferImporter interface that mgm::Buffer should take, that abstracts the importation on behalf of the buffer.
needs info:
755 +void mgx::Display:
756 + EventHandlerReg
757 + DisplayConfigur
758 +{
759 +}
I'm not sure what would happen if the window backing the server changes size. (is this a possible thing for X to do?)
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> 126 + if (buffer_
> mgm::BufferImpo
> Switching on this enum in the buffer type suggests to me that the mgm::Buffer
> should have two different implementations based on the mapping method, or that
> there's mgm::BufferImporter interface that mgm::Buffer should take, that
> abstracts the importation on behalf of the buffer.
I'm not sure I understand what needs to be done here. I've fixed the others.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:2694
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> > 126 + if (buffer_
> > mgm::BufferImpo
> > Switching on this enum in the buffer type suggests to me that the
> mgm::Buffer
> > should have two different implementations based on the mapping method, or
> that
> > there's mgm::BufferImporter interface that mgm::Buffer should take, that
> > abstracts the importation on behalf of the buffer.
>
>
> I'm not sure I understand what needs to be done here. I've fixed the others.
It seems like there's two implementations of mgm::BufferText
GBMNativeTextur
and
DMABufTextureBinder : public mgm::BufferText
and then have mgm::BufferAllo
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
Another round:
1977 + auto dpy = XOpenDisplay(NULL);
nullptr?
1907 +::Display *x_display = nullptr;
1908 +
1909 +mgx::Platform:
IIRC, we guard against opening a platform twice, but we should throw if platform is created twice if this really has to be a singleton. (in the current case, it would leak x_display)
I guess also, x_display should be an RAII type in case either of these throw:
1918 + drm->setup(udev);
1919 + gbm.setup(*drm);
1651 +extern ::Display *x_display;
1400 +extern ::Display *x_display;
These two classes should take this dependency explicitly (as a shared_ptr perhaps), as this guards against ~Platform() being destroyed and destroying the resources that the two classes need.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
931 + return {{0,0}, {width,height}};
could just be:
931 + return {{0,0}, size};
Is calling mgx::Display:
(similar question) should mgx::Display:
1058 + mg::DisplayConf
0 is defined to be invalid (more detail: https:/
1414 + auto ret = true
spacing
365 -struct MesaPlatformIPC
366 +struct DefaultPlatform
"Default" doesn't seem to add much to the name, if it has to be renamed, maybe just PlatformIPCPackage?
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
1189 +void mgx::DisplayGro
1190 +{
1191 +}
There's a bit of a functional difference if we don't do anything here (from mc::MultiThread
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
Inclined to agree with kdub on extracting the buand ffer texture binder RAII for ::Display type.
+ win = XCreateWindow(
Should be the width/height members right?
+ event.key.modifiers = mir_input_
Needs impl or a TODO?
1703: unneeded
+ InputDeviceInfo info;
I can't find where this is initialized?
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> > > 126 + if (buffer_
> > > mgm::BufferImpo
> > > Switching on this enum in the buffer type suggests to me that the
> > mgm::Buffer
> > > should have two different implementations based on the mapping method, or
> > that
> > > there's mgm::BufferImporter interface that mgm::Buffer should take, that
> > > abstracts the importation on behalf of the buffer.
> >
> >
> > I'm not sure I understand what needs to be done here. I've fixed the others.
>
> It seems like there's two implementations of mgm::BufferText
> class in the MP. i.e., it seems more in accord with the existing design to
> have:
>
> GBMNativeTextur
> and
> DMABufTextureBinder : public mgm::BufferText
>
> and then have mgm::BufferAllo
> mgm::Buffer with the right type of BufferTextureBinder
Done.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> Another round:
>
> 1977 + auto dpy = XOpenDisplay(NULL);
> nullptr?
>
> 1907 +::Display *x_display = nullptr;
> 1908 +
> 1909 +mgx::Platform:
> IIRC, we guard against opening a platform twice, but we should throw if
> platform is created twice if this really has to be a singleton. (in the
> current case, it would leak x_display)
>
> I guess also, x_display should be an RAII type in case either of these throw:
> 1918 + drm->setup(udev);
> 1919 + gbm.setup(*drm);
>
> 1651 +extern ::Display *x_display;
> 1400 +extern ::Display *x_display;
> These two classes should take this dependency explicitly (as a shared_ptr
> perhaps), as this guards against ~Platform() being destroyed and destroying
> the resources that the two classes need.
Done.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> Is calling mgx::Display:
> that's not supported?
I currently create an Xwindow that is not resizeable. This is a TODO.
>
> (similar question) should mgx::Display:
> like the VT's work, except of course, if the X server pauses.
I am not sure if there is a need for this. If there is it's another TODO.
Other issues now fixed.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> 1189 +void mgx::DisplayGro
> 1190 +{
> 1191 +}
>
> There's a bit of a functional difference if we don't do anything here (from
> mc::MultiThread
> post the content stored up in the DisplayBuffer in the post() function. Is it
> not possible to separate the swapping from the posting?
I don't see how. X is more like the offscreen or nested in this aspect where this function is null.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> Inclined to agree with kdub on extracting the buand ffer texture binder RAII
> for ::Display type.
>
> + win = XCreateWindow(
>
> Should be the width/height members right?
>
> + event.key.modifiers = mir_input_
>
> Needs impl or a TODO?
This is a TODO.
>
>
> 1703: unneeded
>
> + InputDeviceInfo info;
>
> I can't find where this is initialized?
Ah ok, now fixed.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2698
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:2699
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alberto Aguirre (albaguirre) wrote : Posted in a previous version of this proposal | # |
FAILURE: http://
^--This is a false positive data race:
https:/
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> > (similar question) should mgx::Display:
> somewhat
> > like the VT's work, except of course, if the X server pauses.
>
> I am not sure if there is a need for this. If there is it's another TODO.
We should probably throw then with a runtime not-supported exception. If a client of the x-backed server tried to configure via the client api, the request would be silently ignored.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
1414 +mix::XDispatch
This class has a 2 step initialization; it depends on sink as a dependency of the class, but its not in the constructor. Consider:
mix::XDispatchable dispatch(fd);
dispatch.
The second call would not fulfill what it should be doing (in the case here, it would segfault; if we checked for sink before calling send(), then we would not accomplish the function)
It would be better to plumb through:
mix::XDispatchable dispatch(fd, sink);
so then dispatch.
Kevin DuBois (kdub) wrote : Posted in a previous version of this proposal | # |
> It would be better to plumb through:
> mix::XDispatchable dispatch(fd, sink);
actually, looking through again, it probably has to be:
mix::XDispatchable dispatch(fd, sink, x11_connection);
as that's another dependency of the class. Its not immediately obvious that dispatch() wouldn't work if the Platform class had not instantiated it.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
-- DRMNodeToUse:
Should be
-- DRMNodeToUse:
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
--- src/platforms/
It's better to use an std::unique_ptr with a function deleter. You can use a C function pointer type as opposed to std::function and thus use XCloseDisplay directly and it will be zero overhead.
Otherwise a shared_ptr with a custom deleter is better than a custom type I think.
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
Otherwise, as in if std::unique_ptr is somehow unsuitable
Robert Carr (robertcarr) wrote : Posted in a previous version of this proposal | # |
What is the _wrapper for in + MOCK_METHOD10(
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> 1414 +mix::XDispatch
>
> This class has a 2 step initialization; it depends on sink as a dependency of
> the class, but its not in the constructor. Consider:
>
> mix::XDispatchable dispatch(fd);
> dispatch.
>
> The second call would not fulfill what it should be doing (in the case here,
> it would segfault; if we checked for sink before calling send(), then we would
> not accomplish the function)
>
> It would be better to plumb through:
> mix::XDispatchable dispatch(fd, sink);
> so then dispatch.
> the structure of the system, as we (probably) have to plumb the sink
> dependency a bit differently.
This is due to mi::InputDevice having two distinct functions :
std:
void start(input:
That is, before the InputDevice is started, dispatchable might be obtained and its dispatch() function might be called when there is no sink. In such a case it makes sense to just consume the event but ignore the dispatch which is what the code is doing. I didn't want to change this semantics (of being able to obtain and dispatch even when there is no sink attached) as I don't know what the repercussions would be. It wouldn't crash as the line "if (sink)" is protecting it.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> > It would be better to plumb through:
> > mix::XDispatchable dispatch(fd, sink);
>
> actually, looking through again, it probably has to be:
>
> mix::XDispatchable dispatch(fd, sink, x11_connection);
>
> as that's another dependency of the class. Its not immediately obvious that
> dispatch() wouldn't work if the Platform class had not instantiated it.
x11_connection is an (external) global. I'm going to have to think of something in the long-term but in the short-term we'll need to live with this ugliness. But at least things would fail miserably way before we'd get to this point.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> We should probably throw then with a runtime not-supported exception. If a
> client of the x-backed server tried to configure via the client api, the
> request would be silently ignored.
Fixed
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> --- src/platforms/
> +0000
>
> It's better to use an std::unique_ptr with a function deleter. You can use a C
> function pointer type as opposed to std::function and thus use XCloseDisplay
> directly and it will be zero overhead.
>
> Otherwise a shared_ptr with a custom deleter is better than a custom type I
> think.
I don't think unique_ptr is appropriate as it's being shared between modules. And I'm not worried about the delete overhead - this will only happen when the server goes down, not on every frame or anything like that.
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> What is the _wrapper for in + MOCK_METHOD10(
> Window(Display*, Window, unsigned int, unsigned int, unsigned int, int,
> unsigned int, Visual*, unsigned long, XSetWindowAttri
XCreateWindow takes more than 10 args but gmock accepts up to 10. The way to get around this is to drop some of the uninteresting args and limit the number to 10 with a wrapper. See the response to the original question in : https:/
Cemil Azizoglu (cemil-azizoglu) wrote : Posted in a previous version of this proposal | # |
> -- DRMNodeToUse:
>
> Should be
>
> -- DRMNodeToUse:
Fixed
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:2701
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
Reproposed using the new options branch.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2702
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Chris Halse Rogers (raof) wrote : | # |
Nonblocking:
180 + std::runtime_
std::system_error does this in a better-consumable way without the boost::
234 + dynamic_
235 + dynamic_
What's the need for dynamic_cast here? Both DMABufTextureBinder and NativePixmapTex
763 + eglMakeCurrent(
764 + eglDestroyConte
765 + eglDestroySurfa
Funky indentation.
2880 +TEST_F(
I continue to think that this test doesn't test anything valuable, and should be removed.
Otherwise seems sane.
Alexandros Frantzis (afrantzis) wrote : | # |
186 +
Not sure this empty line improves readability.
~~~~~~~
234 + dynamic_
What Chris said, and also we can use make_unique.
~~~~~~~
723 + eglTerminate(
724 + XDestroyWindow(
731 + eglDestroyConte
732 + eglTerminate(
733 + XDestroyWindow(
750 + XFree(visInfo);
Using RAII wrappers for these types would help us avoid explicit destruction and potential memory leaks (e.g., as things are now we may leak visInfo).
~~~~~~~
1467 + std::chrono:
1549 + ~XDispatchable() = default;
1550 +
1551 + XDispatchable(
1552 + XDispatchable& operator=
No need for explicit default (omitting the destructor creates a default one), or delete (methods are deleted in parent interface class).
~~~~~~~
1925 +std::shared_
It would be better to avoid having static variables hold resources if we can help it. In this case, we could make the x11_connection a member variable of platform, and, if we *really* need to guard against multiple instantiations (which we are not doing in any other platform, btw), we could use a static (atomic) bool variable.
~~~~~~~
2469 +// Window XCreateWindow(
Unnecessary comment.
~~~~~~~
2461 + return global_
3088 + X11Dispatchable
3089 + {
3090 + }
... and at various other places.
A few instances of tabs instead of spaces. Please grep the diff for tabs and replace them.
Alexandros Frantzis (afrantzis) wrote : | # |
1467 + std::chrono:
Is the system_clock the right clock to use? I would expect a monotonic/steady clock, like our android-based input system uses.
Alexandros Frantzis (afrantzis) wrote : | # |
> 1467 + std::chrono:
>
> Is the system_clock the right clock to use? I would expect a monotonic/steady clock,
> like our android-based input system uses.
A scratch this, we are not measuring time with the clock, just converting units.
Robert Carr (robertcarr) wrote : | # |
732 + eglTerminate(
733 + XDestroyWindow(
+ other places in this ctor
are strong evidence EGLDisplay and the XWindow should be an RAII type.
Robert Carr (robertcarr) wrote : | # |
Lots of indentaiton errors but otherwise seems ok to me :D
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2707
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alan Griffiths (alan-griffiths) wrote : | # |
I try running:
$ bin/mir_demo_server --test-client bin/mir_
And see a window containing a titlebar. But no triangle.
Is this expected?
Alan Griffiths (alan-griffiths) wrote : | # |
Also:
$ bin/mir_
Gives a blank window.
Alan Griffiths (alan-griffiths) wrote : | # |
> I try running:
>
> $ bin/mir_demo_server --test-client bin/mir_
>
> And see a window containing a titlebar. But no triangle.
>
> Is this expected?
Apparently so - I've got an intel GPU and there are driver issues with EGL clients.
Alan Griffiths (alan-griffiths) wrote : | # |
$ bin/mir_demo_server --platform-
This draws OK, but e.g. Shift+F11/Ctrl+F11 do not toggle the surface vertical/horizontal maximize. (And Alt+F4, Ctrl+F4 are intercepted before hitting the server.)
What's the expectation?
Alan Griffiths (alan-griffiths) wrote : | # |
212 +template<typename T,typename V>
213 +T up_cast(V x) {
214 + return x;
215 +}
216 +
...
239 + // To see why up_cast is needed, see
240 + // http://
241 std::unique_
242 - new EGLImageBufferT
243 + buffer_
244 + up_cast<
245 + up_cast<
Personally, I wouldn't write an up_cast<> template for this (people will need to look at the definition to follow the code). Instead:
auto make_texture_
BufferImpor
std:
std:
=> std::unique_
{
if (buffer_
return std::make_
else
return std::make_
}
...
auto const buffer =
Alan Griffiths (alan-griffiths) wrote : | # |
Just nits so far. (May well be more if I re-read the code later.)
127 +
Neededless whitespace
~~~~
485 +namespace mgmh = mgm::helpers;
unused.
~~~~
511 -
Helpful whitespace
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
> $ bin/mir_demo_server --platform-
> mesa-x11.so.3 --test-client bin/mir_
>
> This draws OK, but e.g. Shift+F11/Ctrl+F11 do not toggle the surface
> vertical/horizontal maximize. (And Alt+F4, Ctrl+F4 are intercepted before
> hitting the server.)
>
> What's the expectation?
Meta keys are not handled yet.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2709
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2710
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
I have addressed all the reviews so far with the exception of the following :
alf - static variables hold resources
1925 +std::shared_
The problem here is that our graphics and input platforms do not share any context and this is a TODO. I'd rather not spend any more time on what amounts to a bandaid solution.
-------
chris - this test doesn't test anything valuable, and should be removed.
2880 +TEST_F(
This test is pretty similar on other platforms. I'd like to keep it so I can refine it.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2713
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alexandros Frantzis (afrantzis) wrote : | # |
Looks good.
Alan Griffiths (alan-griffiths) wrote : | # |
I'd rather have this code on trunk than wait for known gaps to be filled (EGL clients, missing meta key input and mouse input).
Kevin DuBois (kdub) wrote : | # |
> I have addressed all the reviews so far with the exception of the following :
>
> alf - static variables hold resources
> 1925 +std::shared_
>
> The problem here is that our graphics and input platforms do not share any
> context and this is a TODO. I'd rather not spend any more time on what amounts
> to a bandaid solution.
The issue though is that its a non-explicit (ie, not in the destructor) dependency of the classes that use it, which makes the classes that use it a bit trickier. +1 in the name of not spending more time, but would be better with a TODO comment, I think.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:2713
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
Thanks for this work, I'm waiting for this since some time, as it will help a lot the development.
As per inline comment, I guess symbols should be updated to platform 4.
Also, I think that a new mir-platform-
Cemil Azizoglu (cemil-azizoglu) wrote : | # |
> Thanks for this work, I'm waiting for this since some time, as it will help a
> lot the development.
>
> As per inline comment, I guess symbols should be updated to platform 4.
>
> Also, I think that a new mir-platform-
> generated.
Thanks for noticing this. Fixed now.
We don't yet have a package for this. X11 support is still pretty raw. Getting the minimally acceptable code to the trunk is the first priority, which is not necessarily equivalent to having a minimally functional x11 platform support.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:2715
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) : | # |
Marco Trevisan (Treviño) (3v1n0) wrote : | # |
> We don't yet have a package for this. X11 support is still pretty raw.
Ok, thanks, fair enough.
Probably, one thing to add is to grab the mouse input (and hide the X cursor) when the Mir on X window is focused, or it will be hard to interact without disturbing the environment :), but things seem to start working pretty well (also launching it in a wily LXC container on a trusty host with 3.19 [vivid lts] kernel).
Preview Diff
1 | === modified file 'CMakeLists.txt' |
2 | --- CMakeLists.txt 2015-07-16 07:03:19 +0000 |
3 | +++ CMakeLists.txt 2015-07-22 20:26:39 +0000 |
4 | @@ -144,10 +144,10 @@ |
5 | # Default to KMS backend, but build all of them |
6 | set( |
7 | MIR_PLATFORM |
8 | - mesa-kms;android |
9 | + mesa-kms;android;mesa-x11 |
10 | CACHE |
11 | STRING |
12 | - "a list of graphics backends to build (options are 'mesa-kms' or 'android')" |
13 | + "a list of graphics backends to build (options are 'mesa-kms', 'android' or 'mesa-x11')" |
14 | ) |
15 | |
16 | list(GET MIR_PLATFORM 0 MIR_TEST_PLATFORM) |
17 | @@ -159,6 +159,9 @@ |
18 | if (platform STREQUAL "android") |
19 | set(MIR_BUILD_PLATFORM_ANDROID TRUE) |
20 | endif() |
21 | + if (platform STREQUAL "mesa-x11") |
22 | + set(MIR_BUILD_PLATFORM_MESA_X11 TRUE) |
23 | + endif() |
24 | endforeach(platform) |
25 | |
26 | find_package(EGL REQUIRED) |
27 | @@ -182,7 +185,7 @@ |
28 | find_package(LibHardware REQUIRED) |
29 | endif() |
30 | |
31 | -if (MIR_BUILD_PLATFORM_MESA_KMS) |
32 | +if (MIR_BUILD_PLATFORM_MESA_KMS OR MIR_BUILD_PLATFORM_MESA_X11) |
33 | find_package( PkgConfig ) |
34 | pkg_check_modules( GBM REQUIRED gbm>=9.0.0) |
35 | pkg_check_modules( DRM REQUIRED libdrm ) |
36 | |
37 | === modified file 'src/platforms/CMakeLists.txt' |
38 | --- src/platforms/CMakeLists.txt 2015-07-21 07:09:45 +0000 |
39 | +++ src/platforms/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
40 | @@ -52,8 +52,8 @@ |
41 | |
42 | add_subdirectory(common/) |
43 | |
44 | -if (MIR_BUILD_PLATFORM_MESA_KMS) |
45 | - add_subdirectory(mesa/) |
46 | +if (MIR_BUILD_PLATFORM_MESA_KMS OR MIR_BUILD_PLATFORM_MESA_X11) |
47 | + add_subdirectory(mesa/) |
48 | endif() |
49 | |
50 | if (MIR_BUILD_PLATFORM_ANDROID) |
51 | |
52 | === modified file 'src/platforms/mesa/server/CMakeLists.txt' |
53 | --- src/platforms/mesa/server/CMakeLists.txt 2015-06-05 06:28:36 +0000 |
54 | +++ src/platforms/mesa/server/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
55 | @@ -3,3 +3,6 @@ |
56 | if (MIR_BUILD_PLATFORM_MESA_KMS) |
57 | add_subdirectory(kms/) |
58 | endif() |
59 | +if (MIR_BUILD_PLATFORM_MESA_X11) |
60 | + add_subdirectory(x11/) |
61 | +endif() |
62 | |
63 | === modified file 'src/platforms/mesa/server/common/buffer_allocator.cpp' |
64 | --- src/platforms/mesa/server/common/buffer_allocator.cpp 2015-07-17 22:51:35 +0000 |
65 | +++ src/platforms/mesa/server/common/buffer_allocator.cpp 2015-07-22 20:26:39 +0000 |
66 | @@ -22,10 +22,12 @@ |
67 | #include "buffer_texture_binder.h" |
68 | #include "anonymous_shm_file.h" |
69 | #include "shm_buffer.h" |
70 | +#include "display_helpers.h" |
71 | #include "mir/graphics/egl_extensions.h" |
72 | #include "mir/graphics/egl_error.h" |
73 | #include "mir/graphics/buffer_properties.h" |
74 | #include <boost/throw_exception.hpp> |
75 | +#include <boost/exception/errinfo_errno.hpp> |
76 | |
77 | #include <EGL/egl.h> |
78 | #include <EGL/eglext.h> |
79 | @@ -37,6 +39,7 @@ |
80 | #include <system_error> |
81 | #include <gbm.h> |
82 | #include <cassert> |
83 | +#include <fcntl.h> |
84 | |
85 | namespace mg = mir::graphics; |
86 | namespace mgm = mg::mesa; |
87 | @@ -50,7 +53,9 @@ |
88 | public: |
89 | EGLImageBufferTextureBinder(std::shared_ptr<gbm_bo> const& gbm_bo, |
90 | std::shared_ptr<mg::EGLExtensions> const& egl_extensions) |
91 | - : bo{gbm_bo}, egl_extensions{egl_extensions}, egl_image{EGL_NO_IMAGE_KHR} |
92 | + : bo{gbm_bo}, |
93 | + egl_extensions{egl_extensions}, |
94 | + egl_image{EGL_NO_IMAGE_KHR} |
95 | { |
96 | } |
97 | |
98 | @@ -68,6 +73,24 @@ |
99 | egl_extensions->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, egl_image); |
100 | } |
101 | |
102 | +protected: |
103 | + virtual void ensure_egl_image() = 0; |
104 | + |
105 | + std::shared_ptr<gbm_bo> const bo; |
106 | + std::shared_ptr<mg::EGLExtensions> const egl_extensions; |
107 | + EGLDisplay egl_display; |
108 | + EGLImageKHR egl_image; |
109 | +}; |
110 | + |
111 | +class NativePixmapTextureBinder : public EGLImageBufferTextureBinder |
112 | +{ |
113 | +public: |
114 | + NativePixmapTextureBinder(std::shared_ptr<gbm_bo> const& gbm_bo, |
115 | + std::shared_ptr<mg::EGLExtensions> const& egl_extensions) |
116 | + : EGLImageBufferTextureBinder(gbm_bo, egl_extensions) |
117 | + { |
118 | + } |
119 | + |
120 | private: |
121 | void ensure_egl_image() |
122 | { |
123 | @@ -82,19 +105,71 @@ |
124 | EGL_NONE |
125 | }; |
126 | |
127 | - egl_image = egl_extensions->eglCreateImageKHR(egl_display, EGL_NO_CONTEXT, |
128 | + egl_image = egl_extensions->eglCreateImageKHR(egl_display, |
129 | + EGL_NO_CONTEXT, |
130 | EGL_NATIVE_PIXMAP_KHR, |
131 | reinterpret_cast<void*>(bo_raw), |
132 | image_attrs); |
133 | if (egl_image == EGL_NO_IMAGE_KHR) |
134 | - BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create EGLImage from GBM bo")); |
135 | - } |
136 | - } |
137 | - |
138 | - std::shared_ptr<gbm_bo> const bo; |
139 | - std::shared_ptr<mg::EGLExtensions> const egl_extensions; |
140 | - EGLDisplay egl_display; |
141 | - EGLImageKHR egl_image; |
142 | + BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create EGLImage")); |
143 | + } |
144 | + } |
145 | +}; |
146 | + |
147 | +class DMABufTextureBinder : public EGLImageBufferTextureBinder |
148 | +{ |
149 | +public: |
150 | + DMABufTextureBinder(std::shared_ptr<gbm_bo> const& gbm_bo, |
151 | + std::shared_ptr<mg::EGLExtensions> const& egl_extensions) |
152 | + : EGLImageBufferTextureBinder(gbm_bo, egl_extensions) |
153 | + { |
154 | + } |
155 | + |
156 | +private: |
157 | + void ensure_egl_image() |
158 | + { |
159 | + if (egl_image == EGL_NO_IMAGE_KHR) |
160 | + { |
161 | + egl_display = eglGetCurrentDisplay(); |
162 | + gbm_bo* bo_raw{bo.get()}; |
163 | + |
164 | + auto device = gbm_bo_get_device(bo_raw); |
165 | + auto gem_handle = gbm_bo_get_handle(bo_raw).u32; |
166 | + auto drm_fd = gbm_device_get_fd(device); |
167 | + int raw_fd = -1; |
168 | + |
169 | + auto ret = drmPrimeHandleToFD(drm_fd, gem_handle, DRM_CLOEXEC, &raw_fd); |
170 | + prime_fd = mir::Fd{raw_fd}; |
171 | + if (ret) |
172 | + { |
173 | + std::string const msg("Failed to get PRIME fd from gbm bo"); |
174 | + BOOST_THROW_EXCEPTION( |
175 | + std::system_error(errno, std::system_category(), "Failed to get PRIME fd from gbm bo")); |
176 | + } |
177 | + |
178 | + const EGLint image_attrs_X[] = |
179 | + { |
180 | + EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, |
181 | + EGL_WIDTH, static_cast<const EGLint>(gbm_bo_get_width(bo_raw)), |
182 | + EGL_HEIGHT, static_cast<const EGLint>(gbm_bo_get_height(bo_raw)), |
183 | + EGL_LINUX_DRM_FOURCC_EXT, static_cast<const EGLint>(gbm_bo_get_format(bo_raw)), |
184 | + EGL_DMA_BUF_PLANE0_FD_EXT, prime_fd, |
185 | + EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, |
186 | + EGL_DMA_BUF_PLANE0_PITCH_EXT, static_cast<const EGLint>(gbm_bo_get_stride(bo_raw)), |
187 | + EGL_NONE |
188 | + }; |
189 | + |
190 | + egl_image = egl_extensions->eglCreateImageKHR(egl_display, |
191 | + EGL_NO_CONTEXT, |
192 | + EGL_LINUX_DMA_BUF_EXT, |
193 | + static_cast<EGLClientBuffer>(nullptr), |
194 | + image_attrs_X); |
195 | + if (egl_image == EGL_NO_IMAGE_KHR) |
196 | + BOOST_THROW_EXCEPTION(mg::egl_error("Failed to create EGLImage")); |
197 | + } |
198 | + } |
199 | + |
200 | + mir::Fd prime_fd; |
201 | }; |
202 | |
203 | struct GBMBODeleter |
204 | @@ -106,15 +181,30 @@ |
205 | } |
206 | }; |
207 | |
208 | +auto make_texture_binder( |
209 | + mgm::BufferImportMethod const buffer_import_method, |
210 | + std::shared_ptr<gbm_bo> const& bo, |
211 | + std::shared_ptr<mg::EGLExtensions> const& egl_extensions) |
212 | +-> std::unique_ptr<EGLImageBufferTextureBinder> |
213 | +{ |
214 | + if (buffer_import_method == mgm::BufferImportMethod::dma_buf) |
215 | + return std::make_unique<DMABufTextureBinder>(bo, egl_extensions); |
216 | + else |
217 | + return std::make_unique<NativePixmapTextureBinder>(bo, egl_extensions); |
218 | +} |
219 | + |
220 | } |
221 | |
222 | mgm::BufferAllocator::BufferAllocator( |
223 | gbm_device* device, |
224 | - BypassOption bypass_option) |
225 | + BypassOption bypass_option, |
226 | + mgm::BufferImportMethod const buffer_import_method) |
227 | : device(device), |
228 | egl_extensions(std::make_shared<mg::EGLExtensions>()), |
229 | - bypass_option(bypass_option) |
230 | - |
231 | + bypass_option(buffer_import_method == mgm::BufferImportMethod::dma_buf ? |
232 | + mgm::BypassOption::prohibited : |
233 | + bypass_option), |
234 | + buffer_import_method(buffer_import_method) |
235 | { |
236 | } |
237 | |
238 | @@ -169,12 +259,9 @@ |
239 | |
240 | std::shared_ptr<gbm_bo> bo{bo_raw, GBMBODeleter()}; |
241 | |
242 | - std::unique_ptr<EGLImageBufferTextureBinder> texture_binder{ |
243 | - new EGLImageBufferTextureBinder{bo, egl_extensions}}; |
244 | - |
245 | /* Create the GBMBuffer */ |
246 | auto const buffer = |
247 | - std::make_shared<GBMBuffer>(bo, bo_flags, std::move(texture_binder)); |
248 | + std::make_shared<GBMBuffer>(bo, bo_flags, make_texture_binder(buffer_import_method, bo, egl_extensions)); |
249 | |
250 | return buffer; |
251 | } |
252 | @@ -257,5 +344,5 @@ |
253 | return std::make_unique<mgm::GBMBuffer>( |
254 | bo, |
255 | package->flags, |
256 | - std::make_unique<EGLImageBufferTextureBinder>(bo, egl_extensions)); |
257 | + std::make_unique<NativePixmapTextureBinder>(bo, egl_extensions)); |
258 | } |
259 | |
260 | === modified file 'src/platforms/mesa/server/common/buffer_allocator.h' |
261 | --- src/platforms/mesa/server/common/buffer_allocator.h 2015-07-16 07:03:19 +0000 |
262 | +++ src/platforms/mesa/server/common/buffer_allocator.h 2015-07-22 20:26:39 +0000 |
263 | @@ -38,10 +38,17 @@ |
264 | |
265 | namespace mesa |
266 | { |
267 | + |
268 | +enum class BufferImportMethod |
269 | +{ |
270 | + gbm_native_pixmap, |
271 | + dma_buf |
272 | +}; |
273 | + |
274 | class BufferAllocator: public graphics::GraphicBufferAllocator |
275 | { |
276 | public: |
277 | - BufferAllocator(gbm_device* device, BypassOption bypass_option); |
278 | + BufferAllocator(gbm_device* device, BypassOption bypass_option, BufferImportMethod const buffer_import_method); |
279 | |
280 | virtual std::shared_ptr<Buffer> alloc_buffer( |
281 | graphics::BufferProperties const& buffer_properties); |
282 | @@ -60,6 +67,7 @@ |
283 | std::shared_ptr<EGLExtensions> const egl_extensions; |
284 | |
285 | BypassOption const bypass_option; |
286 | + BufferImportMethod const buffer_import_method; |
287 | }; |
288 | |
289 | } |
290 | |
291 | === modified file 'src/platforms/mesa/server/common/display_helpers.cpp' |
292 | --- src/platforms/mesa/server/common/display_helpers.cpp 2015-06-17 05:20:42 +0000 |
293 | +++ src/platforms/mesa/server/common/display_helpers.cpp 2015-07-22 20:26:39 +0000 |
294 | @@ -56,6 +56,9 @@ |
295 | std::runtime_error( |
296 | "Tried to get authenticated DRM fd before setting up the DRM master")); |
297 | |
298 | + if (node_to_use == DRMNodeToUse::render) |
299 | + return mir::Fd{IntOwnedFd{dup(fd)}}; |
300 | + |
301 | char* busid = drmGetBusid(fd); |
302 | if (!busid) |
303 | BOOST_THROW_EXCEPTION( |
304 | @@ -199,13 +202,16 @@ |
305 | |
306 | mir::udev::Enumerator devices(udev); |
307 | devices.match_subsystem("drm"); |
308 | - devices.match_sysname("card[0-9]*"); |
309 | + if (node_to_use == DRMNodeToUse::render) |
310 | + devices.match_sysname("renderD[0-9]*"); |
311 | + else |
312 | + devices.match_sysname("card[0-9]*"); |
313 | |
314 | devices.scan_devices(); |
315 | |
316 | for(auto& device : devices) |
317 | { |
318 | - if ((error = is_appropriate_device(udev, device))) |
319 | + if ((node_to_use == DRMNodeToUse::card) && (error = is_appropriate_device(udev, device))) |
320 | continue; |
321 | |
322 | // If directly opening the DRM device is good enough for X it's good enough for us! |
323 | @@ -216,26 +222,31 @@ |
324 | continue; |
325 | } |
326 | |
327 | - // Check that the drm device is usable by setting the interface version we use (1.4) |
328 | - drmSetVersion sv; |
329 | - sv.drm_di_major = 1; |
330 | - sv.drm_di_minor = 4; |
331 | - sv.drm_dd_major = -1; /* Don't care */ |
332 | - sv.drm_dd_minor = -1; /* Don't care */ |
333 | - |
334 | - if ((error = -drmSetInterfaceVersion(tmp_fd, &sv))) |
335 | + if (node_to_use == DRMNodeToUse::card) |
336 | { |
337 | + // Check that the drm device is usable by setting the interface version we use (1.4) |
338 | + drmSetVersion sv; |
339 | + sv.drm_di_major = 1; |
340 | + sv.drm_di_minor = 4; |
341 | + sv.drm_dd_major = -1; /* Don't care */ |
342 | + sv.drm_dd_minor = -1; /* Don't care */ |
343 | + |
344 | + if ((error = -drmSetInterfaceVersion(tmp_fd, &sv))) |
345 | + { |
346 | + close(tmp_fd); |
347 | + tmp_fd = -1; |
348 | + continue; |
349 | + } |
350 | + |
351 | + // Stop if this device has connections to display on |
352 | + if (count_connections(tmp_fd) > 0) |
353 | + break; |
354 | + |
355 | close(tmp_fd); |
356 | tmp_fd = -1; |
357 | - continue; |
358 | } |
359 | - |
360 | - // Stop if this device has connections to display on |
361 | - if (count_connections(tmp_fd) > 0) |
362 | + else |
363 | break; |
364 | - |
365 | - close(tmp_fd); |
366 | - tmp_fd = -1; |
367 | } |
368 | |
369 | if (tmp_fd < 0) |
370 | |
371 | === modified file 'src/platforms/mesa/server/common/display_helpers.h' |
372 | --- src/platforms/mesa/server/common/display_helpers.h 2015-06-17 05:20:42 +0000 |
373 | +++ src/platforms/mesa/server/common/display_helpers.h 2015-07-22 20:26:39 +0000 |
374 | @@ -48,10 +48,16 @@ |
375 | namespace helpers |
376 | { |
377 | |
378 | +enum class DRMNodeToUse |
379 | +{ |
380 | + render, |
381 | + card |
382 | +}; |
383 | + |
384 | class DRMHelper : public DRMAuthentication |
385 | { |
386 | public: |
387 | - DRMHelper() : fd{-1} {} |
388 | + DRMHelper(DRMNodeToUse const node_to_use) : fd{-1}, node_to_use{node_to_use} {} |
389 | ~DRMHelper(); |
390 | |
391 | DRMHelper(const DRMHelper &) = delete; |
392 | @@ -65,6 +71,7 @@ |
393 | void set_master() const; |
394 | |
395 | int fd; |
396 | + DRMNodeToUse const node_to_use; |
397 | |
398 | private: |
399 | // TODO: This herustic is temporary; should be replaced with |
400 | |
401 | === modified file 'src/platforms/mesa/server/common/ipc_operations.cpp' |
402 | --- src/platforms/mesa/server/common/ipc_operations.cpp 2015-06-17 05:20:42 +0000 |
403 | +++ src/platforms/mesa/server/common/ipc_operations.cpp 2015-07-22 20:26:39 +0000 |
404 | @@ -53,8 +53,7 @@ |
405 | }; |
406 | } |
407 | |
408 | -mgm::IpcOperations::IpcOperations(std::shared_ptr<DRMAuthentication> const& drm_auth) : |
409 | - drm_auth{drm_auth} |
410 | +mgm::IpcOperations::IpcOperations(std::shared_ptr<DRMAuthentication> const& drm) : drm{drm} |
411 | { |
412 | } |
413 | |
414 | @@ -103,7 +102,7 @@ |
415 | |
416 | try |
417 | { |
418 | - drm_auth->auth_magic(auth_magic_request.magic); |
419 | + drm->auth_magic(auth_magic_request.magic); |
420 | auth_magic_response.status = 0; |
421 | } |
422 | catch (std::exception const& e) |
423 | @@ -129,7 +128,7 @@ |
424 | std::runtime_error("Invalid request message for auth_fd platform operation")); |
425 | } |
426 | |
427 | - return mg::PlatformOperationMessage{{},{drm_auth->authenticated_fd()}}; |
428 | + return mg::PlatformOperationMessage{{},{drm->authenticated_fd()}}; |
429 | } |
430 | else |
431 | { |
432 | @@ -140,5 +139,5 @@ |
433 | |
434 | std::shared_ptr<mg::PlatformIPCPackage> mgm::IpcOperations::connection_ipc_package() |
435 | { |
436 | - return std::make_shared<MesaPlatformIPCPackage>(drm_auth->authenticated_fd()); |
437 | + return std::make_shared<MesaPlatformIPCPackage>(drm->authenticated_fd()); |
438 | } |
439 | |
440 | === modified file 'src/platforms/mesa/server/common/ipc_operations.h' |
441 | --- src/platforms/mesa/server/common/ipc_operations.h 2015-06-17 05:20:42 +0000 |
442 | +++ src/platforms/mesa/server/common/ipc_operations.h 2015-07-22 20:26:39 +0000 |
443 | @@ -31,7 +31,7 @@ |
444 | class IpcOperations : public PlatformIpcOperations |
445 | { |
446 | public: |
447 | - IpcOperations(std::shared_ptr<DRMAuthentication> const&); |
448 | + IpcOperations(std::shared_ptr<DRMAuthentication> const& drm); |
449 | |
450 | void pack_buffer(BufferIpcMessage& message, Buffer const& buffer, BufferIpcMsgType msg_type) const override; |
451 | void unpack_buffer(BufferIpcMessage& message, Buffer const& buffer) const override; |
452 | @@ -40,7 +40,7 @@ |
453 | unsigned int const opcode, |
454 | PlatformOperationMessage const& message) override; |
455 | private: |
456 | - std::shared_ptr<DRMAuthentication> const drm_auth; |
457 | + std::shared_ptr<DRMAuthentication> const drm; |
458 | }; |
459 | |
460 | } |
461 | |
462 | === modified file 'src/platforms/mesa/server/kms/guest_platform.cpp' |
463 | --- src/platforms/mesa/server/kms/guest_platform.cpp 2015-07-16 07:03:19 +0000 |
464 | +++ src/platforms/mesa/server/kms/guest_platform.cpp 2015-07-22 20:26:39 +0000 |
465 | @@ -80,12 +80,12 @@ |
466 | gbm.setup(fds.at(0)); |
467 | set_guest_gbm_device(*nested_context, gbm.device); |
468 | ipc_ops = std::make_shared<mgm::IpcOperations>( |
469 | - std::make_shared<mgm::NestedAuthentication>(nested_context)); |
470 | + std::make_shared<mgm::NestedAuthentication>(nested_context)); |
471 | } |
472 | |
473 | std::shared_ptr<mg::GraphicBufferAllocator> mgm::GuestPlatform::create_buffer_allocator() |
474 | { |
475 | - return std::make_shared<mgm::BufferAllocator>(gbm.device, mgm::BypassOption::prohibited); |
476 | + return std::make_shared<mgm::BufferAllocator>(gbm.device, mgm::BypassOption::prohibited, mgm::BufferImportMethod::gbm_native_pixmap); |
477 | } |
478 | |
479 | std::shared_ptr<mg::Platform> create_guest_platform( |
480 | |
481 | === modified file 'src/platforms/mesa/server/kms/platform.cpp' |
482 | --- src/platforms/mesa/server/kms/platform.cpp 2015-07-17 17:23:11 +0000 |
483 | +++ src/platforms/mesa/server/kms/platform.cpp 2015-07-22 20:26:39 +0000 |
484 | @@ -39,6 +39,7 @@ |
485 | |
486 | namespace mg = mir::graphics; |
487 | namespace mgm = mg::mesa; |
488 | +namespace mgmh = mgm::helpers; |
489 | namespace mo = mir::options; |
490 | |
491 | namespace |
492 | @@ -128,7 +129,7 @@ |
493 | EmergencyCleanupRegistry& emergency_cleanup_registry, |
494 | BypassOption bypass_option) |
495 | : udev{std::make_shared<mir::udev::Context>()}, |
496 | - drm{std::make_shared<helpers::DRMHelper>()}, |
497 | + drm{std::make_shared<mgmh::DRMHelper>(mgmh::DRMNodeToUse::card)}, |
498 | listener{listener}, |
499 | vt{vt}, |
500 | bypass_option_{bypass_option} |
501 | @@ -137,7 +138,7 @@ |
502 | gbm.setup(*drm); |
503 | |
504 | std::weak_ptr<VirtualTerminal> weak_vt = vt; |
505 | - std::weak_ptr<helpers::DRMHelper> weak_drm = drm; |
506 | + std::weak_ptr<mgmh::DRMHelper> weak_drm = drm; |
507 | emergency_cleanup_registry.add( |
508 | [weak_vt,weak_drm] |
509 | { |
510 | @@ -151,7 +152,7 @@ |
511 | |
512 | std::shared_ptr<mg::GraphicBufferAllocator> mgm::Platform::create_buffer_allocator() |
513 | { |
514 | - return std::make_shared<mgm::BufferAllocator>(gbm.device, bypass_option_); |
515 | + return std::make_shared<mgm::BufferAllocator>(gbm.device, bypass_option_, mgm::BufferImportMethod::gbm_native_pixmap); |
516 | } |
517 | |
518 | std::shared_ptr<mg::Display> mgm::Platform::create_display( |
519 | @@ -184,7 +185,7 @@ |
520 | std::shared_ptr<mg::Platform> create_host_platform( |
521 | std::shared_ptr<mo::Option> const& options, |
522 | std::shared_ptr<mir::EmergencyCleanupRegistry> const& emergency_cleanup_registry, |
523 | - std::shared_ptr<mir::graphics::DisplayReport> const& report) |
524 | + std::shared_ptr<mg::DisplayReport> const& report) |
525 | { |
526 | auto real_fops = std::make_shared<RealVTFileOperations>(); |
527 | auto real_pops = std::unique_ptr<RealPosixProcessOperations>(new RealPosixProcessOperations{}); |
528 | |
529 | === added directory 'src/platforms/mesa/server/x11' |
530 | === added file 'src/platforms/mesa/server/x11/CMakeLists.txt' |
531 | --- src/platforms/mesa/server/x11/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
532 | +++ src/platforms/mesa/server/x11/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
533 | @@ -0,0 +1,61 @@ |
534 | +include_directories( |
535 | + ${server_common_include_dirs} |
536 | + ${PROJECT_SOURCE_DIR}/include/platform |
537 | + ${PROJECT_SOURCE_DIR}/include/client |
538 | + ${PROJECT_SOURCE_DIR}/src/platforms/mesa/server/common |
539 | +) |
540 | + |
541 | +include_directories( |
542 | + ${DRM_INCLUDE_DIRS} |
543 | + ${GBM_INCLUDE_DIRS} |
544 | + ${EGL_INCLUDE_DIRS} |
545 | + ${GLESv2_INCLUDE_DIRS} |
546 | + ${UDEV_INCLUDE_DIRS} |
547 | +) |
548 | + |
549 | +add_library( |
550 | + mirplatformservermesax11objects OBJECT |
551 | + |
552 | + platform.cpp |
553 | + display.cpp |
554 | + display_configuration.cpp |
555 | + gl_context.cpp |
556 | + display_group.cpp |
557 | + display_buffer.cpp |
558 | + input/input.cpp |
559 | + input/input_platform.cpp |
560 | + input/input_device.cpp |
561 | + input/dispatchable.cpp |
562 | +) |
563 | + |
564 | +add_library( |
565 | + mirplatformservermesax11 MODULE |
566 | + |
567 | + $<TARGET_OBJECTS:mirplatformservermesax11objects> |
568 | +) |
569 | + |
570 | +target_link_libraries( |
571 | + mirplatformservermesax11 |
572 | + PRIVATE |
573 | + mirplatform |
574 | + EGL |
575 | + GLESv2 |
576 | + X11 |
577 | + mirsharedmesaservercommon-static |
578 | + ${Boost_PROGRAM_OPTIONS_LIBRARY} |
579 | + ${DRM_LDFLAGS} ${DRM_LIBRARIES} |
580 | + ${GBM_LDFLAGS} ${GBM_LIBRARIES} |
581 | +) |
582 | + |
583 | +set(symbol_map ${CMAKE_CURRENT_SOURCE_DIR}/symbols.map) |
584 | + |
585 | +set_target_properties( |
586 | + mirplatformservermesax11 PROPERTIES |
587 | + OUTPUT_NAME server-mesa-x11 |
588 | + LIBRARY_OUTPUT_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/server-modules |
589 | + PREFIX "" |
590 | + SUFFIX ".so.${MIR_SERVER_GRAPHICS_PLATFORM_ABI}" |
591 | + LINK_FLAGS "-Wl,--exclude-libs=ALL -Wl,--version-script,${symbol_map}" |
592 | +) |
593 | + |
594 | +install(TARGETS mirplatformservermesax11 LIBRARY DESTINATION ${MIR_SERVER_PLATFORM_PATH}) |
595 | |
596 | === added file 'src/platforms/mesa/server/x11/display.cpp' |
597 | --- src/platforms/mesa/server/x11/display.cpp 1970-01-01 00:00:00 +0000 |
598 | +++ src/platforms/mesa/server/x11/display.cpp 2015-07-22 20:26:39 +0000 |
599 | @@ -0,0 +1,274 @@ |
600 | +/* |
601 | + * Copyright © 2015 Canonical Ltd. |
602 | + * |
603 | + * This program is free software: you can redistribute it and/or modify it |
604 | + * under the terms of the GNU Lesser General Public License version 3, |
605 | + * as published by the Free Software Foundation. |
606 | + * |
607 | + * This program is distributed in the hope that it will be useful, |
608 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
609 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
610 | + * GNU Lesser General Public License for more details. |
611 | + * |
612 | + * You should have received a copy of the GNU Lesser General Public License |
613 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
614 | + * |
615 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
616 | + */ |
617 | + |
618 | +#include "mir/graphics/platform.h" |
619 | +#include "mir/graphics/display_report.h" |
620 | +#include "mir/graphics/egl_resources.h" |
621 | +#include "mir/graphics/egl_error.h" |
622 | +#include "display_configuration.h" |
623 | +#include "display.h" |
624 | +#include "display_buffer.h" |
625 | +#include "gl_context.h" |
626 | + |
627 | +#include <boost/throw_exception.hpp> |
628 | +#include <fcntl.h> |
629 | +#include <mutex> |
630 | + |
631 | +#define MIR_LOG_COMPONENT "x11-display" |
632 | +#include "mir/log.h" |
633 | + |
634 | +namespace mg=mir::graphics; |
635 | +namespace mgx=mg::X; |
636 | +namespace geom=mir::geometry; |
637 | + |
638 | +mgx::X11EGLDisplay::X11EGLDisplay(::Display *x_dpy) |
639 | + : egl_dpy{eglGetDisplay(x_dpy)} |
640 | +{ |
641 | + if (!egl_dpy) |
642 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot get an egl display")); |
643 | + |
644 | + EGLint egl_major, egl_minor; |
645 | + if (!eglInitialize(egl_dpy, &egl_major, &egl_minor)) |
646 | + BOOST_THROW_EXCEPTION(mg::egl_error("eglInitialize failed")); |
647 | + |
648 | + mir::log_info("EGL Version %d.%d", egl_major, egl_minor); |
649 | +} |
650 | + |
651 | +mgx::X11EGLDisplay::~X11EGLDisplay() |
652 | +{ |
653 | + eglTerminate(egl_dpy); |
654 | +} |
655 | + |
656 | +mgx::X11EGLDisplay::operator EGLDisplay() const |
657 | +{ |
658 | + return egl_dpy; |
659 | +} |
660 | + |
661 | +mgx::X11Window::X11Window(::Display *x_dpy, EGLDisplay egl_dpy, int width, int height) |
662 | + : x_dpy{x_dpy} |
663 | +{ |
664 | + EGLint const att[] = { |
665 | + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
666 | + EGL_RED_SIZE, 5, |
667 | + EGL_GREEN_SIZE, 5, |
668 | + EGL_BLUE_SIZE, 5, |
669 | + EGL_ALPHA_SIZE, 0, |
670 | + EGL_DEPTH_SIZE, 0, |
671 | + EGL_STENCIL_SIZE, 0, |
672 | + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
673 | + EGL_NONE |
674 | + }; |
675 | + |
676 | + auto root = XDefaultRootWindow(x_dpy); |
677 | + |
678 | + EGLint num_configs; |
679 | + if (!eglChooseConfig(egl_dpy, att, &config, 1, &num_configs)) |
680 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot get an EGL config")); |
681 | + |
682 | + assert(config); |
683 | + assert(num_configs > 0); |
684 | + |
685 | + EGLint vid; |
686 | + if (!eglGetConfigAttrib(egl_dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) |
687 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot get config attrib")); |
688 | + |
689 | + XVisualInfo visTemplate; |
690 | + int num_visuals; |
691 | + visTemplate.visualid = vid; |
692 | + auto visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals); |
693 | + if (!visInfo) |
694 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot get visual info")); |
695 | + |
696 | + XSetWindowAttributes attr; |
697 | + attr.background_pixel = 0; |
698 | + attr.border_pixel = 0; |
699 | + attr.colormap = XCreateColormap(x_dpy, root, visInfo->visual, AllocNone); |
700 | + attr.event_mask = StructureNotifyMask | |
701 | + ExposureMask | |
702 | + KeyPressMask | |
703 | + KeyReleaseMask | |
704 | + ButtonPressMask | |
705 | + ButtonReleaseMask; |
706 | + |
707 | + auto mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; |
708 | + |
709 | + win = XCreateWindow(x_dpy, root, 0, 0, width, height, |
710 | + 0, visInfo->depth, InputOutput, |
711 | + visInfo->visual, mask, &attr); |
712 | + |
713 | + mir::log_info("Pixel depth = %d", visInfo->depth); |
714 | + |
715 | + //TODO: handle others |
716 | + assert(visInfo->depth==24); |
717 | + |
718 | + XFree(visInfo); |
719 | + |
720 | + XMapWindow(x_dpy, win); |
721 | +} |
722 | + |
723 | +mgx::X11Window::~X11Window() |
724 | +{ |
725 | + XDestroyWindow(x_dpy, win); |
726 | +} |
727 | + |
728 | +mgx::X11Window::operator Window() const |
729 | +{ |
730 | + return win; |
731 | +} |
732 | + |
733 | +EGLConfig mgx::X11Window::egl_config() const |
734 | +{ |
735 | + return config; |
736 | +} |
737 | + |
738 | +mgx::X11EGLContext::X11EGLContext(EGLDisplay egl_dpy, EGLConfig config) |
739 | + : egl_dpy{egl_dpy} |
740 | +{ |
741 | + static const EGLint ctx_attribs[] = { |
742 | + EGL_CONTEXT_CLIENT_VERSION, 2, |
743 | + EGL_NONE }; |
744 | + |
745 | + egl_ctx = eglCreateContext(egl_dpy, config, EGL_NO_CONTEXT, ctx_attribs); |
746 | + if (!egl_ctx) |
747 | + BOOST_THROW_EXCEPTION(mg::egl_error("eglCreateContext failed")); |
748 | +} |
749 | + |
750 | +mgx::X11EGLContext::~X11EGLContext() |
751 | +{ |
752 | + eglDestroyContext(egl_dpy, egl_ctx); |
753 | +} |
754 | + |
755 | +mgx::X11EGLContext::operator EGLContext() const |
756 | +{ |
757 | + return egl_ctx; |
758 | +} |
759 | + |
760 | +mgx::X11EGLSurface::X11EGLSurface(EGLDisplay egl_dpy, EGLConfig config, Window win) |
761 | + : egl_dpy{egl_dpy}, egl_surf{eglCreateWindowSurface(egl_dpy, config, win, NULL)} |
762 | +{ |
763 | + if (!egl_surf) |
764 | + BOOST_THROW_EXCEPTION(mg::egl_error("eglCreateWindowSurface failed")); |
765 | +} |
766 | + |
767 | +mgx::X11EGLSurface::~X11EGLSurface() |
768 | +{ |
769 | + eglDestroySurface(egl_dpy, egl_surf); |
770 | +} |
771 | + |
772 | +mgx::X11EGLSurface::operator EGLSurface() const |
773 | +{ |
774 | + return egl_surf; |
775 | +} |
776 | + |
777 | +mgx::Display::Display(::Display *dpy) |
778 | + : x_dpy{dpy}, |
779 | + egl_display{X11EGLDisplay(dpy)}, |
780 | + display_width{1280}, |
781 | + display_height{1024}, |
782 | + win{X11Window(dpy, |
783 | + egl_display, |
784 | + display_width, |
785 | + display_height)}, |
786 | + egl_context{X11EGLContext(egl_display, |
787 | + win.egl_config())}, |
788 | + egl_surface{X11EGLSurface(egl_display, |
789 | + win.egl_config(), |
790 | + win)} |
791 | +{ |
792 | + // TODO: read from the chosen config |
793 | + pf = mir_pixel_format_bgr_888; |
794 | + |
795 | + // Make window nonresizeable |
796 | + // TODO: Make sizing possible |
797 | + { |
798 | + char const * const title = "Mir On X"; |
799 | + XSizeHints sizehints; |
800 | + |
801 | + sizehints.x = 0; |
802 | + sizehints.y = 0; |
803 | + sizehints.base_width = display_width; |
804 | + sizehints.base_height = display_height; |
805 | + sizehints.min_width = display_width; |
806 | + sizehints.min_height = display_height; |
807 | + sizehints.max_width = display_width; |
808 | + sizehints.max_height = display_height; |
809 | + sizehints.flags = USSize | USPosition | PMinSize | PMaxSize; |
810 | + |
811 | + XSetNormalHints(x_dpy, win, &sizehints); |
812 | + XSetStandardProperties(x_dpy, win, title, title, None, (char **)NULL, 0, &sizehints); |
813 | + } |
814 | + |
815 | + display_group = std::make_unique<mgx::DisplayGroup>( |
816 | + std::make_unique<mgx::DisplayBuffer>(geom::Size{display_width, display_height}, |
817 | + egl_display, |
818 | + egl_surface, |
819 | + egl_context)); |
820 | +} |
821 | + |
822 | +mgx::Display::~Display() noexcept |
823 | +{ |
824 | + eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
825 | +} |
826 | + |
827 | +void mgx::Display::for_each_display_sync_group(std::function<void(mg::DisplaySyncGroup&)> const& f) |
828 | +{ |
829 | + f(*display_group); |
830 | +} |
831 | + |
832 | +std::unique_ptr<mg::DisplayConfiguration> mgx::Display::configuration() const |
833 | +{ |
834 | + return std::make_unique<mgx::DisplayConfiguration>(pf, display_width, display_height); |
835 | +} |
836 | + |
837 | +void mgx::Display::configure(mg::DisplayConfiguration const& /*new_configuration*/) |
838 | +{ |
839 | + BOOST_THROW_EXCEPTION(std::runtime_error("'Display::configure()' not yet supported on x11 platform")); |
840 | +} |
841 | + |
842 | +void mgx::Display::register_configuration_change_handler( |
843 | + EventHandlerRegister& /* event_handler*/, |
844 | + DisplayConfigurationChangeHandler const& /*change_handler*/) |
845 | +{ |
846 | +} |
847 | + |
848 | +void mgx::Display::register_pause_resume_handlers( |
849 | + EventHandlerRegister& /*handlers*/, |
850 | + DisplayPauseHandler const& /*pause_handler*/, |
851 | + DisplayResumeHandler const& /*resume_handler*/) |
852 | +{ |
853 | +} |
854 | + |
855 | +void mgx::Display::pause() |
856 | +{ |
857 | + BOOST_THROW_EXCEPTION(std::runtime_error("'Display::pause()' not yet supported on x11 platform")); |
858 | +} |
859 | + |
860 | +void mgx::Display::resume() |
861 | +{ |
862 | + BOOST_THROW_EXCEPTION(std::runtime_error("'Display::resume()' not yet supported on x11 platform")); |
863 | +} |
864 | + |
865 | +auto mgx::Display::create_hardware_cursor(std::shared_ptr<mg::CursorImage> const& /* initial_image */) -> std::shared_ptr<Cursor> |
866 | +{ |
867 | + return nullptr; |
868 | +} |
869 | + |
870 | +std::unique_ptr<mg::GLContext> mgx::Display::create_gl_context() |
871 | +{ |
872 | + return std::make_unique<mgx::XGLContext>(egl_display, egl_surface, egl_context); |
873 | +} |
874 | |
875 | === added file 'src/platforms/mesa/server/x11/display.h' |
876 | --- src/platforms/mesa/server/x11/display.h 1970-01-01 00:00:00 +0000 |
877 | +++ src/platforms/mesa/server/x11/display.h 2015-07-22 20:26:39 +0000 |
878 | @@ -0,0 +1,131 @@ |
879 | +/* |
880 | + * Copyright © 2015 Canonical Ltd. |
881 | + * |
882 | + * This program is free software: you can redistribute it and/or modify it |
883 | + * under the terms of the GNU Lesser General Public License version 3, |
884 | + * as published by the Free Software Foundation. |
885 | + * |
886 | + * This program is distributed in the hope that it will be useful, |
887 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
888 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
889 | + * GNU Lesser General Public License for more details. |
890 | + * |
891 | + * You should have received a copy of the GNU Lesser General Public License |
892 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
893 | + * |
894 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
895 | + */ |
896 | + |
897 | +#ifndef MIR_GRAPHICS_X_DISPLAY_H_ |
898 | +#define MIR_GRAPHICS_X_DISPLAY_H_ |
899 | + |
900 | +#include "mir/graphics/display.h" |
901 | +#include "mir_toolkit/common.h" |
902 | +#include "display_group.h" |
903 | + |
904 | +#include <X11/Xlib.h> |
905 | +#include <X11/Xutil.h> |
906 | +#include <EGL/egl.h> |
907 | + |
908 | +namespace mir |
909 | +{ |
910 | +namespace graphics |
911 | +{ |
912 | +namespace X |
913 | +{ |
914 | + |
915 | +class X11EGLDisplay |
916 | +{ |
917 | +public: |
918 | + X11EGLDisplay(::Display *x_dpy); |
919 | + ~X11EGLDisplay(); |
920 | + |
921 | + operator EGLDisplay() const; |
922 | + |
923 | +private: |
924 | + EGLDisplay const egl_dpy; |
925 | +}; |
926 | + |
927 | +class X11Window |
928 | +{ |
929 | +public: |
930 | + X11Window(::Display* const x_dpy, EGLDisplay egl_dpy, int width, int height); |
931 | + ~X11Window(); |
932 | + |
933 | + operator Window() const; |
934 | + EGLConfig egl_config() const; |
935 | + |
936 | +private: |
937 | + ::Display* const x_dpy; |
938 | + Window win; |
939 | + EGLConfig config; |
940 | +}; |
941 | + |
942 | +class X11EGLContext |
943 | +{ |
944 | +public: |
945 | + X11EGLContext(EGLDisplay egl_dpy, EGLConfig config); |
946 | + ~X11EGLContext(); |
947 | + |
948 | + operator EGLContext() const; |
949 | + |
950 | +private: |
951 | + EGLContext egl_ctx; |
952 | + EGLDisplay const egl_dpy; |
953 | +}; |
954 | + |
955 | +class X11EGLSurface |
956 | +{ |
957 | +public: |
958 | + X11EGLSurface(EGLDisplay egl_dpy, EGLConfig config, Window win); |
959 | + ~X11EGLSurface(); |
960 | + |
961 | + operator EGLSurface() const; |
962 | + |
963 | +private: |
964 | + EGLDisplay const egl_dpy; |
965 | + EGLSurface const egl_surf; |
966 | +}; |
967 | + |
968 | +class Display : public graphics::Display |
969 | +{ |
970 | +public: |
971 | + explicit Display(::Display *dpy); |
972 | + ~Display() noexcept; |
973 | + |
974 | + void for_each_display_sync_group(std::function<void(graphics::DisplaySyncGroup&)> const& f) override; |
975 | + |
976 | + std::unique_ptr<graphics::DisplayConfiguration> configuration() const override; |
977 | + void configure(graphics::DisplayConfiguration const&) override; |
978 | + |
979 | + void register_configuration_change_handler( |
980 | + EventHandlerRegister& handlers, |
981 | + DisplayConfigurationChangeHandler const& conf_change_handler) override; |
982 | + |
983 | + void register_pause_resume_handlers( |
984 | + EventHandlerRegister& handlers, |
985 | + DisplayPauseHandler const& pause_handler, |
986 | + DisplayResumeHandler const& resume_handler) override; |
987 | + |
988 | + void pause() override; |
989 | + void resume() override; |
990 | + |
991 | + std::shared_ptr<Cursor> create_hardware_cursor(std::shared_ptr<CursorImage> const& initial_image) override; |
992 | + std::unique_ptr<graphics::GLContext> create_gl_context() override; |
993 | + |
994 | +private: |
995 | + ::Display *x_dpy; |
996 | + X11EGLDisplay const egl_display; |
997 | + int const display_width; |
998 | + int const display_height; |
999 | + X11Window const win; |
1000 | + X11EGLContext egl_context; |
1001 | + X11EGLSurface egl_surface; |
1002 | + MirPixelFormat pf; |
1003 | + std::unique_ptr<DisplayGroup> display_group; |
1004 | +}; |
1005 | + |
1006 | +} |
1007 | +} |
1008 | +} |
1009 | +#endif /* MIR_GRAPHICS_X_DISPLAY_H_ */ |
1010 | |
1011 | === added file 'src/platforms/mesa/server/x11/display_buffer.cpp' |
1012 | --- src/platforms/mesa/server/x11/display_buffer.cpp 1970-01-01 00:00:00 +0000 |
1013 | +++ src/platforms/mesa/server/x11/display_buffer.cpp 2015-07-22 20:26:39 +0000 |
1014 | @@ -0,0 +1,68 @@ |
1015 | +/* |
1016 | + * Copyright © 2015 Canonical Ltd. |
1017 | + * |
1018 | + * This program is free software: you can redistribute it and/or modify it |
1019 | + * under the terms of the GNU Lesser General Public License version 3, |
1020 | + * as published by the Free Software Foundation. |
1021 | + * |
1022 | + * This program is distributed in the hope that it will be useful, |
1023 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1024 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1025 | + * GNU Lesser General Public License for more details. |
1026 | + * |
1027 | + * You should have received a copy of the GNU Lesser General Public License |
1028 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1029 | + * |
1030 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1031 | + * |
1032 | + */ |
1033 | + |
1034 | +#include "mir/graphics/egl_error.h" |
1035 | +#include "display_buffer.h" |
1036 | + |
1037 | +#include <boost/throw_exception.hpp> |
1038 | + |
1039 | +namespace mg=mir::graphics; |
1040 | +namespace mgx=mg::X; |
1041 | +namespace geom=mir::geometry; |
1042 | + |
1043 | +mgx::DisplayBuffer::DisplayBuffer(geom::Size const sz, |
1044 | + EGLDisplay const d, |
1045 | + EGLSurface const s, |
1046 | + EGLContext const c) |
1047 | + : size{sz}, egl_dpy{d}, egl_surf{s}, egl_ctx{c} |
1048 | +{ |
1049 | +} |
1050 | + |
1051 | +geom::Rectangle mgx::DisplayBuffer::view_area() const |
1052 | +{ |
1053 | + return {{0,0}, size}; |
1054 | +} |
1055 | + |
1056 | +void mgx::DisplayBuffer::make_current() |
1057 | +{ |
1058 | + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) |
1059 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot make current")); |
1060 | +} |
1061 | + |
1062 | +void mgx::DisplayBuffer::release_current() |
1063 | +{ |
1064 | + if (!eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) |
1065 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot make uncurrent")); |
1066 | +} |
1067 | + |
1068 | +bool mgx::DisplayBuffer::post_renderables_if_optimizable(RenderableList const& /*renderlist*/) |
1069 | +{ |
1070 | + return false; |
1071 | +} |
1072 | + |
1073 | +void mgx::DisplayBuffer::gl_swap_buffers() |
1074 | +{ |
1075 | + if (!eglSwapBuffers(egl_dpy, egl_surf)) |
1076 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot swap")); |
1077 | +} |
1078 | + |
1079 | +MirOrientation mgx::DisplayBuffer::orientation() const |
1080 | +{ |
1081 | + return mir_orientation_normal; |
1082 | +} |
1083 | |
1084 | === added file 'src/platforms/mesa/server/x11/display_buffer.h' |
1085 | --- src/platforms/mesa/server/x11/display_buffer.h 1970-01-01 00:00:00 +0000 |
1086 | +++ src/platforms/mesa/server/x11/display_buffer.h 2015-07-22 20:26:39 +0000 |
1087 | @@ -0,0 +1,59 @@ |
1088 | +/* |
1089 | + * Copyright © 2015 Canonical Ltd. |
1090 | + * |
1091 | + * This program is free software: you can redistribute it and/or modify it |
1092 | + * under the terms of the GNU Lesser General Public License version 3, |
1093 | + * as published by the Free Software Foundation. |
1094 | + * |
1095 | + * This program is distributed in the hope that it will be useful, |
1096 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1097 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1098 | + * GNU Lesser General Public License for more details. |
1099 | + * |
1100 | + * You should have received a copy of the GNU Lesser General Public License |
1101 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1102 | + * |
1103 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1104 | + * |
1105 | + */ |
1106 | + |
1107 | +#ifndef MIR_GRAPHICS_X_DISPLAY_BUFFER_H_ |
1108 | +#define MIR_GRAPHICS_X_DISPLAY_BUFFER_H_ |
1109 | + |
1110 | +#include "mir/graphics/display_buffer.h" |
1111 | +#include "gl_context.h" |
1112 | + |
1113 | +#include <EGL/egl.h> |
1114 | + |
1115 | +namespace mir |
1116 | +{ |
1117 | +namespace graphics |
1118 | +{ |
1119 | +namespace X |
1120 | +{ |
1121 | + |
1122 | +class DisplayBuffer : public graphics::DisplayBuffer |
1123 | +{ |
1124 | +public: |
1125 | + DisplayBuffer(geometry::Size const sz, EGLDisplay const d, EGLSurface const s, EGLContext const c); |
1126 | + |
1127 | + geometry::Rectangle view_area() const override; |
1128 | + void make_current() override; |
1129 | + void release_current() override; |
1130 | + void gl_swap_buffers() override; |
1131 | + bool post_renderables_if_optimizable(RenderableList const& renderlist) override; |
1132 | + |
1133 | + MirOrientation orientation() const override; |
1134 | + |
1135 | +private: |
1136 | + geometry::Size const size; |
1137 | + EGLDisplay const egl_dpy; |
1138 | + EGLSurface const egl_surf; |
1139 | + EGLContext const egl_ctx; |
1140 | +}; |
1141 | + |
1142 | +} |
1143 | +} |
1144 | +} |
1145 | + |
1146 | +#endif /* MIR_GRAPHICS_X_DISPLAY_BUFFER_H_ */ |
1147 | |
1148 | === added file 'src/platforms/mesa/server/x11/display_configuration.cpp' |
1149 | --- src/platforms/mesa/server/x11/display_configuration.cpp 1970-01-01 00:00:00 +0000 |
1150 | +++ src/platforms/mesa/server/x11/display_configuration.cpp 2015-07-22 20:26:39 +0000 |
1151 | @@ -0,0 +1,63 @@ |
1152 | +/* |
1153 | + * Copyright © 2015 Canonical Ltd. |
1154 | + * |
1155 | + * This program is free software: you can redistribute it and/or modify it |
1156 | + * under the terms of the GNU Lesser General Public License version 3, |
1157 | + * as published by the Free Software Foundation. |
1158 | + * |
1159 | + * This program is distributed in the hope that it will be useful, |
1160 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1161 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1162 | + * GNU Lesser General Public License for more details. |
1163 | + * |
1164 | + * You should have received a copy of the GNU Lesser General Public License |
1165 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1166 | + * |
1167 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1168 | + * |
1169 | + */ |
1170 | + |
1171 | +#include "display_configuration.h" |
1172 | +#include <boost/throw_exception.hpp> |
1173 | + |
1174 | +namespace mg = mir::graphics; |
1175 | +namespace mgx = mg::X; |
1176 | +namespace geom = mir::geometry; |
1177 | + |
1178 | +mgx::DisplayConfiguration::DisplayConfiguration(MirPixelFormat pf, int width, int height) : |
1179 | + configuration{ |
1180 | + mg::DisplayConfigurationOutputId{1}, |
1181 | + mg::DisplayConfigurationCardId{0}, |
1182 | + mg::DisplayConfigurationOutputType::unknown, |
1183 | + {pf}, |
1184 | + //TODO: query fps |
1185 | + {mg::DisplayConfigurationMode{geom::Size{width, height}, 60.0}}, |
1186 | + 0, |
1187 | + //TODO: query mm-size |
1188 | + geom::Size{width, height}, |
1189 | + true, |
1190 | + true, |
1191 | + geom::Point{0, 0}, |
1192 | + 0, |
1193 | + pf, |
1194 | + mir_power_mode_on, |
1195 | + mir_orientation_normal}, |
1196 | + card{mg::DisplayConfigurationCardId{0}, 1} |
1197 | +{ |
1198 | +} |
1199 | + |
1200 | +void mgx::DisplayConfiguration::for_each_card(std::function<void(mg::DisplayConfigurationCard const&)> f) const |
1201 | +{ |
1202 | + f(card); |
1203 | +} |
1204 | + |
1205 | +void mgx::DisplayConfiguration::for_each_output(std::function<void(mg::DisplayConfigurationOutput const&)> f) const |
1206 | +{ |
1207 | + f(configuration); |
1208 | +} |
1209 | + |
1210 | +void mgx::DisplayConfiguration::for_each_output(std::function<void(mg::UserDisplayConfigurationOutput&)> f) |
1211 | +{ |
1212 | + mg::UserDisplayConfigurationOutput user(configuration); |
1213 | + f(user); |
1214 | +} |
1215 | |
1216 | === added file 'src/platforms/mesa/server/x11/display_configuration.h' |
1217 | --- src/platforms/mesa/server/x11/display_configuration.h 1970-01-01 00:00:00 +0000 |
1218 | +++ src/platforms/mesa/server/x11/display_configuration.h 2015-07-22 20:26:39 +0000 |
1219 | @@ -0,0 +1,52 @@ |
1220 | +/* |
1221 | + * Copyright © 2015 Canonical Ltd. |
1222 | + * |
1223 | + * This program is free software: you can redistribute it and/or modify it |
1224 | + * under the terms of the GNU Lesser General Public License version 3, |
1225 | + * as published by the Free Software Foundation. |
1226 | + * |
1227 | + * This program is distributed in the hope that it will be useful, |
1228 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1229 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1230 | + * GNU Lesser General Public License for more details. |
1231 | + * |
1232 | + * You should have received a copy of the GNU Lesser General Public License |
1233 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1234 | + * |
1235 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1236 | + * |
1237 | + */ |
1238 | + |
1239 | +#ifndef MIR_GRAPHICS_X_DISPLAY_CONFIGURATION_H_ |
1240 | +#define MIR_GRAPHICS_X_DISPLAY_CONFIGURATION_H_ |
1241 | + |
1242 | +#include "mir/graphics/display_configuration.h" |
1243 | + |
1244 | +namespace mir |
1245 | +{ |
1246 | +namespace graphics |
1247 | +{ |
1248 | +namespace X |
1249 | +{ |
1250 | + |
1251 | +class DisplayConfiguration : public graphics::DisplayConfiguration |
1252 | +{ |
1253 | +public: |
1254 | + DisplayConfiguration(MirPixelFormat pf, int width, int height); |
1255 | + |
1256 | + virtual ~DisplayConfiguration() = default; |
1257 | + |
1258 | + void for_each_card(std::function<void(DisplayConfigurationCard const&)> f) const override; |
1259 | + void for_each_output(std::function<void(DisplayConfigurationOutput const&)> f) const override; |
1260 | + void for_each_output(std::function<void(UserDisplayConfigurationOutput&)> f) override; |
1261 | + |
1262 | +private: |
1263 | + DisplayConfigurationOutput configuration; |
1264 | + DisplayConfigurationCard card; |
1265 | +}; |
1266 | + |
1267 | + |
1268 | +} |
1269 | +} |
1270 | +} |
1271 | +#endif /* MIR_GRAPHICS_X_DISPLAY_CONFIGURATION_H_ */ |
1272 | |
1273 | === added file 'src/platforms/mesa/server/x11/display_group.cpp' |
1274 | --- src/platforms/mesa/server/x11/display_group.cpp 1970-01-01 00:00:00 +0000 |
1275 | +++ src/platforms/mesa/server/x11/display_group.cpp 2015-07-22 20:26:39 +0000 |
1276 | @@ -0,0 +1,42 @@ |
1277 | +/* |
1278 | + * Copyright © 2015 Canonical Ltd. |
1279 | + * |
1280 | + * This program is free software: you can redistribute it and/or modify it |
1281 | + * under the terms of the GNU Lesser General Public License version 3, |
1282 | + * as published by the Free Software Foundation. |
1283 | + * |
1284 | + * This program is distributed in the hope that it will be useful, |
1285 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1286 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1287 | + * GNU Lesser General Public License for more details. |
1288 | + * |
1289 | + * You should have received a copy of the GNU Lesser General Public License |
1290 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1291 | + * |
1292 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1293 | + * |
1294 | + */ |
1295 | + |
1296 | +#include "display_group.h" |
1297 | + |
1298 | +namespace mg = mir::graphics; |
1299 | +namespace mgx = mg::X; |
1300 | + |
1301 | +mgx::DisplayGroup::DisplayGroup(std::unique_ptr<mgx::DisplayBuffer> primary_buffer) |
1302 | +{ |
1303 | + display_buffer = std::move(primary_buffer); |
1304 | +} |
1305 | + |
1306 | +void mgx::DisplayGroup::for_each_display_buffer(std::function<void(mg::DisplayBuffer&)> const& f) |
1307 | +{ |
1308 | + f(*display_buffer); |
1309 | +} |
1310 | + |
1311 | +void mgx::DisplayGroup::post() |
1312 | +{ |
1313 | +} |
1314 | + |
1315 | +std::chrono::milliseconds mgx::DisplayGroup::recommended_sleep() const |
1316 | +{ |
1317 | + return std::chrono::milliseconds::zero(); |
1318 | +} |
1319 | |
1320 | === added file 'src/platforms/mesa/server/x11/display_group.h' |
1321 | --- src/platforms/mesa/server/x11/display_group.h 1970-01-01 00:00:00 +0000 |
1322 | +++ src/platforms/mesa/server/x11/display_group.h 2015-07-22 20:26:39 +0000 |
1323 | @@ -0,0 +1,51 @@ |
1324 | +/* |
1325 | + * Copyright © 2015 Canonical Ltd. |
1326 | + * |
1327 | + * This program is free software: you can redistribute it and/or modify it |
1328 | + * under the terms of the GNU Lesser General Public License version 3, |
1329 | + * as published by the Free Software Foundation. |
1330 | + * |
1331 | + * This program is distributed in the hope that it will be useful, |
1332 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1333 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1334 | + * GNU Lesser General Public License for more details. |
1335 | + * |
1336 | + * You should have received a copy of the GNU Lesser General Public License |
1337 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1338 | + * |
1339 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1340 | + * |
1341 | + */ |
1342 | + |
1343 | +#ifndef MIR_GRAPHICS_X_DISPLAY_GROUP_H_ |
1344 | +#define MIR_GRAPHICS_X_DISPLAY_GROUP_H_ |
1345 | + |
1346 | +#include "mir_toolkit/common.h" |
1347 | +#include "mir/graphics/display.h" |
1348 | +#include "display_buffer.h" |
1349 | + |
1350 | +namespace mir |
1351 | +{ |
1352 | +namespace graphics |
1353 | +{ |
1354 | +namespace X |
1355 | +{ |
1356 | + |
1357 | +class DisplayGroup : public graphics::DisplaySyncGroup |
1358 | +{ |
1359 | +public: |
1360 | + DisplayGroup(std::unique_ptr<DisplayBuffer> primary_buffer); |
1361 | + |
1362 | + void for_each_display_buffer(std::function<void(graphics::DisplayBuffer&)> const& f) override; |
1363 | + void post() override; |
1364 | + std::chrono::milliseconds recommended_sleep() const override; |
1365 | + |
1366 | +private: |
1367 | + std::unique_ptr<DisplayBuffer> display_buffer; |
1368 | +}; |
1369 | + |
1370 | +} |
1371 | +} |
1372 | +} |
1373 | + |
1374 | +#endif /* MIR_GRAPHICS_X_DISPLAY_GROUP_H_ */ |
1375 | |
1376 | === added file 'src/platforms/mesa/server/x11/gl_context.cpp' |
1377 | --- src/platforms/mesa/server/x11/gl_context.cpp 1970-01-01 00:00:00 +0000 |
1378 | +++ src/platforms/mesa/server/x11/gl_context.cpp 2015-07-22 20:26:39 +0000 |
1379 | @@ -0,0 +1,45 @@ |
1380 | +/* |
1381 | + * Copyright © 2015 Canonical Ltd. |
1382 | + * |
1383 | + * This program is free software: you can redistribute it and/or modify it |
1384 | + * under the terms of the GNU Lesser General Public License version 3, |
1385 | + * as published by the Free Software Foundation. |
1386 | + * |
1387 | + * This program is distributed in the hope that it will be useful, |
1388 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1389 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1390 | + * GNU Lesser General Public License for more details. |
1391 | + * |
1392 | + * You should have received a copy of the GNU Lesser General Public License |
1393 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1394 | + * |
1395 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1396 | + * |
1397 | + */ |
1398 | + |
1399 | +#include "mir/graphics/egl_error.h" |
1400 | +#include "gl_context.h" |
1401 | +#include <boost/throw_exception.hpp> |
1402 | +#include <stdexcept> |
1403 | + |
1404 | +namespace mg=mir::graphics; |
1405 | +namespace mgx=mg::X; |
1406 | + |
1407 | +mgx::XGLContext::XGLContext(EGLDisplay const d, EGLSurface const s, EGLContext const c) |
1408 | + : egl_dpy{d}, |
1409 | + egl_surf{s}, |
1410 | + egl_ctx{c} |
1411 | +{ |
1412 | +} |
1413 | + |
1414 | +void mgx::XGLContext::make_current() const |
1415 | +{ |
1416 | + if (!eglMakeCurrent(egl_dpy, egl_surf, egl_surf, egl_ctx)) |
1417 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot make current")); |
1418 | +} |
1419 | + |
1420 | +void mgx::XGLContext::release_current() const |
1421 | +{ |
1422 | + if (!eglMakeCurrent(egl_dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) |
1423 | + BOOST_THROW_EXCEPTION(mg::egl_error("Cannot make uncurrent")); |
1424 | +} |
1425 | |
1426 | === added file 'src/platforms/mesa/server/x11/gl_context.h' |
1427 | --- src/platforms/mesa/server/x11/gl_context.h 1970-01-01 00:00:00 +0000 |
1428 | +++ src/platforms/mesa/server/x11/gl_context.h 2015-07-22 20:26:39 +0000 |
1429 | @@ -0,0 +1,52 @@ |
1430 | +/* |
1431 | + * Copyright © 2015 Canonical Ltd. |
1432 | + * |
1433 | + * This program is free software: you can redistribute it and/or modify it |
1434 | + * under the terms of the GNU Lesser General Public License version 3, |
1435 | + * as published by the Free Software Foundation. |
1436 | + * |
1437 | + * This program is distributed in the hope that it will be useful, |
1438 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1439 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1440 | + * GNU Lesser General Public License for more details. |
1441 | + * |
1442 | + * You should have received a copy of the GNU Lesser General Public License |
1443 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1444 | + * |
1445 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1446 | + * |
1447 | + */ |
1448 | + |
1449 | +#ifndef MIR_GRAPHICS_X_GL_CONTEXT_H_ |
1450 | +#define MIR_GRAPHICS_X_GL_CONTEXT_H_ |
1451 | + |
1452 | +#include "mir/graphics/gl_context.h" |
1453 | + |
1454 | +#include <EGL/egl.h> |
1455 | + |
1456 | +namespace mir |
1457 | +{ |
1458 | +namespace graphics |
1459 | +{ |
1460 | +namespace X |
1461 | +{ |
1462 | + |
1463 | +class XGLContext : public graphics::GLContext |
1464 | +{ |
1465 | +public: |
1466 | + XGLContext(EGLDisplay const d, EGLSurface const s, EGLContext const c); |
1467 | + ~XGLContext() = default; |
1468 | + void make_current() const override; |
1469 | + void release_current() const override; |
1470 | + |
1471 | +private: |
1472 | + EGLDisplay const egl_dpy; |
1473 | + EGLSurface const egl_surf; |
1474 | + EGLContext const egl_ctx; |
1475 | +}; |
1476 | + |
1477 | +} |
1478 | +} |
1479 | +} |
1480 | + |
1481 | +#endif /* MIR_GRAPHICS_X_GL_CONTEXT_H_ */ |
1482 | |
1483 | === added directory 'src/platforms/mesa/server/x11/input' |
1484 | === added file 'src/platforms/mesa/server/x11/input/dispatchable.cpp' |
1485 | --- src/platforms/mesa/server/x11/input/dispatchable.cpp 1970-01-01 00:00:00 +0000 |
1486 | +++ src/platforms/mesa/server/x11/input/dispatchable.cpp 2015-07-22 20:26:39 +0000 |
1487 | @@ -0,0 +1,132 @@ |
1488 | +/* |
1489 | + * Copyright © 2015 Canonical Ltd. |
1490 | + * |
1491 | + * This program is free software: you can redistribute it and/or modify it |
1492 | + * under the terms of the GNU General Public License version 3, |
1493 | + * as published by the Free Software Foundation. |
1494 | + * |
1495 | + * This program is distributed in the hope that it will be useful, |
1496 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1497 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1498 | + * GNU General Public License for more details. |
1499 | + * |
1500 | + * You should have received a copy of the GNU General Public License |
1501 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1502 | + * |
1503 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1504 | + */ |
1505 | + |
1506 | +#include "dispatchable.h" |
1507 | +#include "../xserver_connection.h" |
1508 | +#include "mir/events/event_private.h" |
1509 | + |
1510 | +#include <boost/throw_exception.hpp> |
1511 | +#include <chrono> |
1512 | +#include <X11/Xlib.h> |
1513 | +#include <X11/Xutil.h> |
1514 | +#include <linux/input.h> |
1515 | +#include <inttypes.h> |
1516 | + |
1517 | +#define MIR_LOG_COMPONENT "x11-dispatchable" |
1518 | +#include "mir/log.h" |
1519 | + |
1520 | +namespace mi = mir::input; |
1521 | +namespace mix = mi::X; |
1522 | +namespace md = mir::dispatch; |
1523 | +namespace mx = mir::X; |
1524 | + |
1525 | +extern std::shared_ptr<mx::X11Connection> x11_connection; |
1526 | + |
1527 | +mix::XDispatchable::XDispatchable(int raw_fd) |
1528 | + : fd(raw_fd), sink(nullptr) |
1529 | +{ |
1530 | +} |
1531 | + |
1532 | +mir::Fd mix::XDispatchable::watch_fd() const |
1533 | +{ |
1534 | + return fd; |
1535 | +} |
1536 | + |
1537 | +bool mix::XDispatchable::dispatch(md::FdEvents events) |
1538 | +{ |
1539 | + auto ret = true; |
1540 | + |
1541 | + if (events & (md::FdEvent::remote_closed | md::FdEvent::error)) |
1542 | + ret = false; |
1543 | + |
1544 | + if (events & md::FdEvent::readable) |
1545 | + { |
1546 | + XEvent xev; |
1547 | + |
1548 | + XNextEvent(x11_connection->dpy, &xev); |
1549 | + |
1550 | + if (sink) |
1551 | + { |
1552 | + switch (xev.type) |
1553 | + { |
1554 | + case KeyPress: |
1555 | + case KeyRelease: |
1556 | + { |
1557 | + MirEvent event; |
1558 | + XKeyEvent &xkev = (XKeyEvent &)xev; |
1559 | + static const int STRMAX = 32; |
1560 | + char str[STRMAX]; |
1561 | + KeySym keysym; |
1562 | + |
1563 | + auto count = XLookupString(&xkev, str, STRMAX, &keysym, NULL); |
1564 | + |
1565 | + mir::log_info("Key event : type=%d, serial=%u, send_event=%d, display=%p, window=%p, root=%p, subwindow=%p, time=%d, x=%d, y=%d, x_root=%d, y_root=%d, state=%0X, keycode=%d, same_screen=%d", |
1566 | + xkev.type, xkev.serial, xkev.send_event, xkev.display, xkev.window, xkev.root, xkev.subwindow, xkev.time, xkev.x, xkev.y, xkev.x_root, xkev.y_root, xkev.state, xkev.keycode, xkev.same_screen); |
1567 | + |
1568 | + event.key.type = mir_event_type_key; |
1569 | + event.key.device_id = 0; |
1570 | + event.key.source_id = 0; |
1571 | + event.key.action = xev.type == KeyPress ? |
1572 | + mir_keyboard_action_down : mir_keyboard_action_up; |
1573 | + event.key.modifiers = mir_input_event_modifier_none; |
1574 | + event.key.key_code = keysym; |
1575 | + event.key.scan_code = xkev.keycode-8; |
1576 | + |
1577 | + std::chrono::time_point<std::chrono::system_clock> tp; |
1578 | + std::chrono::milliseconds msec(xkev.time); |
1579 | + tp += msec; |
1580 | + event.key.event_time = std::chrono::duration_cast<std::chrono::nanoseconds>(tp.time_since_epoch()); |
1581 | + |
1582 | + for (int i=0; i<count; i++) |
1583 | + mir::log_info("buffer[%d]='%c', key_code=%d, scan_code=%d, event_time=%" PRId64, i, str[i], keysym, xkev.keycode-8, event.key.event_time); |
1584 | + |
1585 | + sink->handle_input(event); |
1586 | + break; |
1587 | + } |
1588 | + |
1589 | + case MappingNotify: |
1590 | + mir::log_info("Mapping changed at server. Refreshing the cache."); |
1591 | + XRefreshKeyboardMapping((XMappingEvent*)&xev); |
1592 | + break; |
1593 | + |
1594 | + default: |
1595 | + mir::log_info("Uninteresting event"); |
1596 | + break; |
1597 | + } |
1598 | + } |
1599 | + else |
1600 | + mir::log_info("input event detected with no sink to handle it"); |
1601 | + } |
1602 | + |
1603 | + return ret; |
1604 | +} |
1605 | + |
1606 | +md::FdEvents mix::XDispatchable::relevant_events() const |
1607 | +{ |
1608 | + return md::FdEvent::readable | md::FdEvent::error | md::FdEvent::remote_closed; |
1609 | +} |
1610 | + |
1611 | +void mix::XDispatchable::set_input_sink(mi::InputSink *input_sink) |
1612 | +{ |
1613 | + sink = input_sink; |
1614 | +} |
1615 | + |
1616 | +void mix::XDispatchable::unset_input_sink() |
1617 | +{ |
1618 | + sink = nullptr; |
1619 | +} |
1620 | |
1621 | === added file 'src/platforms/mesa/server/x11/input/dispatchable.h' |
1622 | --- src/platforms/mesa/server/x11/input/dispatchable.h 1970-01-01 00:00:00 +0000 |
1623 | +++ src/platforms/mesa/server/x11/input/dispatchable.h 2015-07-22 20:26:39 +0000 |
1624 | @@ -0,0 +1,52 @@ |
1625 | +/* |
1626 | + * Copyright © 2015 Canonical Ltd. |
1627 | + * |
1628 | + * This program is free software: you can redistribute it and/or modify it |
1629 | + * under the terms of the GNU Lesser General Public License version 3, |
1630 | + * as published by the Free Software Foundation. |
1631 | + * |
1632 | + * This program is distributed in the hope that it will be useful, |
1633 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1634 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1635 | + * GNU Lesser General Public License for more details. |
1636 | + * |
1637 | + * You should have received a copy of the GNU Lesser General Public License |
1638 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1639 | + * |
1640 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1641 | + */ |
1642 | + |
1643 | +#ifndef MIR_INPUT_X_DISPATCHABLE_H_ |
1644 | +#define MIR_INPUT_X_DISPATCHABLE_H_ |
1645 | + |
1646 | +#include "mir/dispatch/dispatchable.h" |
1647 | +#include "mir/input/input_sink.h" |
1648 | + |
1649 | +namespace mir |
1650 | +{ |
1651 | +namespace input |
1652 | +{ |
1653 | +namespace X |
1654 | +{ |
1655 | +struct XDispatchable : public dispatch::Dispatchable |
1656 | +{ |
1657 | +public: |
1658 | + XDispatchable(int raw_fd); |
1659 | + |
1660 | + mir::Fd watch_fd() const override; |
1661 | + bool dispatch(dispatch::FdEvents events) override; |
1662 | + dispatch::FdEvents relevant_events() const override; |
1663 | + |
1664 | + void set_input_sink(InputSink *input_sink); |
1665 | + void unset_input_sink(); |
1666 | + |
1667 | +private: |
1668 | + mir::Fd fd; |
1669 | + InputSink *sink; |
1670 | +}; |
1671 | + |
1672 | +} |
1673 | +} |
1674 | +} |
1675 | + |
1676 | +#endif // MIR_INPUT_X_DISPATCHABLE_H_ |
1677 | |
1678 | === added file 'src/platforms/mesa/server/x11/input/input.cpp' |
1679 | --- src/platforms/mesa/server/x11/input/input.cpp 1970-01-01 00:00:00 +0000 |
1680 | +++ src/platforms/mesa/server/x11/input/input.cpp 2015-07-22 20:26:39 +0000 |
1681 | @@ -0,0 +1,60 @@ |
1682 | +/* |
1683 | + * Copyright © 2015 Canonical Ltd. |
1684 | + * |
1685 | + * This program is free software: you can redistribute it and/or modify it |
1686 | + * under the terms of the GNU General Public License version 3, |
1687 | + * as published by the Free Software Foundation. |
1688 | + * |
1689 | + * This program is distributed in the hope that it will be useful, |
1690 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1691 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1692 | + * GNU General Public License for more details. |
1693 | + * |
1694 | + * You should have received a copy of the GNU General Public License |
1695 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1696 | + * |
1697 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1698 | + */ |
1699 | + |
1700 | +#include "input_platform.h" |
1701 | +#include "mir/module_properties.h" |
1702 | +#include "mir/input/platform.h" |
1703 | + |
1704 | +namespace mo = mir::options; |
1705 | +namespace mi = mir::input; |
1706 | +namespace mix = mi::X; |
1707 | + |
1708 | +extern "C" mir::UniqueModulePtr<mi::Platform> create_input_platform( |
1709 | + std::shared_ptr<mo::Option> const& /*options*/, |
1710 | + std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/, |
1711 | + std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry, |
1712 | + std::shared_ptr<mi::InputReport> const& /*report*/) |
1713 | +{ |
1714 | + return mir::make_module_ptr<mix::XInputPlatform>(input_device_registry); |
1715 | +} |
1716 | + |
1717 | +extern "C" void add_input_platform_options( |
1718 | + boost::program_options::options_description& /*config*/) |
1719 | +{ |
1720 | +} |
1721 | + |
1722 | +extern "C" mi::PlatformPriority probe_input_platform( |
1723 | + mo::Option const& /*options*/) |
1724 | +{ |
1725 | + return mi::PlatformPriority::best; |
1726 | +} |
1727 | + |
1728 | +namespace |
1729 | +{ |
1730 | +mir::ModuleProperties const description = { |
1731 | + "x11-input", |
1732 | + MIR_VERSION_MAJOR, |
1733 | + MIR_VERSION_MINOR, |
1734 | + MIR_VERSION_MICRO |
1735 | +}; |
1736 | +} |
1737 | + |
1738 | +extern "C" mir::ModuleProperties const* describe_input_module() |
1739 | +{ |
1740 | + return &description; |
1741 | +} |
1742 | |
1743 | === added file 'src/platforms/mesa/server/x11/input/input_device.cpp' |
1744 | --- src/platforms/mesa/server/x11/input/input_device.cpp 1970-01-01 00:00:00 +0000 |
1745 | +++ src/platforms/mesa/server/x11/input/input_device.cpp 2015-07-22 20:26:39 +0000 |
1746 | @@ -0,0 +1,54 @@ |
1747 | +/* |
1748 | + * Copyright © 2015 Canonical Ltd. |
1749 | + * |
1750 | + * This program is free software: you can redistribute it and/or modify it |
1751 | + * under the terms of the GNU General Public License version 3, |
1752 | + * as published by the Free Software Foundation. |
1753 | + * |
1754 | + * This program is distributed in the hope that it will be useful, |
1755 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1756 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1757 | + * GNU General Public License for more details. |
1758 | + * |
1759 | + * You should have received a copy of the GNU General Public License |
1760 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1761 | + * |
1762 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1763 | + */ |
1764 | + |
1765 | +#include "mir/input/input_device_info.h" |
1766 | +#include "input_device.h" |
1767 | +#include "dispatchable.h" |
1768 | +#include "../xserver_connection.h" |
1769 | + |
1770 | +namespace mi = mir::input; |
1771 | +namespace mix = mi::X; |
1772 | +namespace md = mir::dispatch; |
1773 | +namespace mx = mir::X; |
1774 | + |
1775 | +extern std::shared_ptr<mx::X11Connection> x11_connection; |
1776 | + |
1777 | +mix::XInputDevice::XInputDevice() |
1778 | + : fd(XConnectionNumber(x11_connection->dpy)), x_dispatchable(std::make_shared<mix::XDispatchable>(fd)) |
1779 | +{ |
1780 | +} |
1781 | + |
1782 | +std::shared_ptr<md::Dispatchable> mix::XInputDevice::dispatchable() |
1783 | +{ |
1784 | + return x_dispatchable; |
1785 | +} |
1786 | + |
1787 | +void mix::XInputDevice::start(mi::InputSink* destination) |
1788 | +{ |
1789 | + x_dispatchable->set_input_sink(destination); |
1790 | +} |
1791 | + |
1792 | +void mix::XInputDevice::stop() |
1793 | +{ |
1794 | + x_dispatchable->unset_input_sink(); |
1795 | +} |
1796 | + |
1797 | +mi::InputDeviceInfo mix::XInputDevice::get_device_info() |
1798 | +{ |
1799 | + return mi::InputDeviceInfo{0,"x11-keyboard-device","x11-key-dev-1", mi::DeviceCapability::keyboard}; |
1800 | +} |
1801 | |
1802 | === added file 'src/platforms/mesa/server/x11/input/input_device.h' |
1803 | --- src/platforms/mesa/server/x11/input/input_device.h 1970-01-01 00:00:00 +0000 |
1804 | +++ src/platforms/mesa/server/x11/input/input_device.h 2015-07-22 20:26:39 +0000 |
1805 | @@ -0,0 +1,66 @@ |
1806 | +/* |
1807 | + * Copyright © 2015 Canonical Ltd. |
1808 | + * |
1809 | + * This program is free software: you can redistribute it and/or modify it |
1810 | + * under the terms of the GNU Lesser General Public License version 3, |
1811 | + * as published by the Free Software Foundation. |
1812 | + * |
1813 | + * This program is distributed in the hope that it will be useful, |
1814 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1815 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1816 | + * GNU Lesser General Public License for more details. |
1817 | + * |
1818 | + * You should have received a copy of the GNU Lesser General Public License |
1819 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1820 | + * |
1821 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1822 | + */ |
1823 | + |
1824 | +#ifndef MIR_INPUT_X_INPUT_DEVICE_H_ |
1825 | +#define MIR_INPUT_X_INPUT_DEVICE_H_ |
1826 | + |
1827 | +#include "mir/input/input_device.h" |
1828 | + |
1829 | +#include <X11/Xlib.h> |
1830 | + |
1831 | +namespace mir |
1832 | +{ |
1833 | + |
1834 | +namespace dispatch |
1835 | +{ |
1836 | +class Dispatchable; |
1837 | +} |
1838 | + |
1839 | +namespace input |
1840 | +{ |
1841 | + |
1842 | +namespace X |
1843 | +{ |
1844 | +class XDispatchable; |
1845 | + |
1846 | +class XInputDevice : public input::InputDevice |
1847 | +{ |
1848 | +public: |
1849 | + XInputDevice(); |
1850 | + ~XInputDevice() = default; |
1851 | + |
1852 | + std::shared_ptr<dispatch::Dispatchable> dispatchable() override; |
1853 | + void start(input::InputSink* destination) override; |
1854 | + void stop() override; |
1855 | + InputDeviceInfo get_device_info() override; |
1856 | + |
1857 | +protected: |
1858 | + XInputDevice(XInputDevice const&) = delete; |
1859 | + XInputDevice& operator=(XInputDevice const&) = delete; |
1860 | + |
1861 | +private: |
1862 | + int fd; |
1863 | + std::shared_ptr<XDispatchable> x_dispatchable; |
1864 | +}; |
1865 | + |
1866 | +} |
1867 | + |
1868 | +} |
1869 | +} |
1870 | + |
1871 | +#endif // MIR_INPUT_X_INPUT_DEVICE_H_ |
1872 | |
1873 | === added file 'src/platforms/mesa/server/x11/input/input_platform.cpp' |
1874 | --- src/platforms/mesa/server/x11/input/input_platform.cpp 1970-01-01 00:00:00 +0000 |
1875 | +++ src/platforms/mesa/server/x11/input/input_platform.cpp 2015-07-22 20:26:39 +0000 |
1876 | @@ -0,0 +1,51 @@ |
1877 | +/* |
1878 | + * Copyright © 2015 Canonical Ltd. |
1879 | + * |
1880 | + * This program is free software: you can redistribute it and/or modify it |
1881 | + * under the terms of the GNU General Public License version 3, |
1882 | + * as published by the Free Software Foundation. |
1883 | + * |
1884 | + * This program is distributed in the hope that it will be useful, |
1885 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1886 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1887 | + * GNU General Public License for more details. |
1888 | + * |
1889 | + * You should have received a copy of the GNU General Public License |
1890 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1891 | + * |
1892 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1893 | + */ |
1894 | + |
1895 | +#include "input_platform.h" |
1896 | +#include "input_device.h" |
1897 | + |
1898 | +#include "mir/input/input_device_registry.h" |
1899 | +#include "mir/dispatch/action_queue.h" |
1900 | +#include "mir/module_deleter.h" |
1901 | + |
1902 | +namespace mi = mir::input; |
1903 | +namespace md = mir::dispatch; |
1904 | +namespace mix = mi::X; |
1905 | + |
1906 | +mix::XInputPlatform::XInputPlatform( |
1907 | + std::shared_ptr<mi::InputDeviceRegistry> const& input_device_registry) |
1908 | + : platform_queue(mir::make_module_ptr<md::ActionQueue>()), |
1909 | + registry(input_device_registry), |
1910 | + device(std::make_shared<mix::XInputDevice>()) |
1911 | +{ |
1912 | +} |
1913 | + |
1914 | +void mix::XInputPlatform::start() |
1915 | +{ |
1916 | + registry->add_device(device); |
1917 | +} |
1918 | + |
1919 | +std::shared_ptr<md::Dispatchable> mix::XInputPlatform::dispatchable() |
1920 | +{ |
1921 | + return platform_queue; |
1922 | +} |
1923 | + |
1924 | +void mix::XInputPlatform::stop() |
1925 | +{ |
1926 | + registry->remove_device(device); |
1927 | +} |
1928 | |
1929 | === added file 'src/platforms/mesa/server/x11/input/input_platform.h' |
1930 | --- src/platforms/mesa/server/x11/input/input_platform.h 1970-01-01 00:00:00 +0000 |
1931 | +++ src/platforms/mesa/server/x11/input/input_platform.h 2015-07-22 20:26:39 +0000 |
1932 | @@ -0,0 +1,60 @@ |
1933 | +/* |
1934 | + * Copyright © 2015 Canonical Ltd. |
1935 | + * |
1936 | + * This program is free software: you can redistribute it and/or modify it |
1937 | + * under the terms of the GNU General Public License version 3, |
1938 | + * as published by the Free Software Foundation. |
1939 | + * |
1940 | + * This program is distributed in the hope that it will be useful, |
1941 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1942 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1943 | + * GNU General Public License for more details. |
1944 | + * |
1945 | + * You should have received a copy of the GNU General Public License |
1946 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1947 | + * |
1948 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
1949 | + */ |
1950 | +#ifndef MIR_INPUT_X_INPUT_PLATFORM_H_ |
1951 | +#define MIR_INPUT_X_INPUT_PLATFORM_H_ |
1952 | + |
1953 | +#include "mir/input/platform.h" |
1954 | +#include <memory> |
1955 | + |
1956 | +namespace mir |
1957 | +{ |
1958 | + |
1959 | +namespace dispatch |
1960 | +{ |
1961 | +class ActionQueue; |
1962 | +} |
1963 | + |
1964 | +namespace input |
1965 | +{ |
1966 | +class InputDevice; |
1967 | + |
1968 | +namespace X |
1969 | +{ |
1970 | +class XInputDevice; |
1971 | + |
1972 | +class XInputPlatform : public input::Platform |
1973 | +{ |
1974 | +public: |
1975 | + explicit XInputPlatform(std::shared_ptr<input::InputDeviceRegistry> const& input_device_registry); |
1976 | + ~XInputPlatform() = default; |
1977 | + |
1978 | + std::shared_ptr<dispatch::Dispatchable> dispatchable() override; |
1979 | + void start() override; |
1980 | + void stop() override; |
1981 | + |
1982 | +private: |
1983 | + std::shared_ptr<dispatch::ActionQueue> const platform_queue; |
1984 | + std::shared_ptr<input::InputDeviceRegistry> const registry; |
1985 | + std::shared_ptr<XInputDevice> const device; |
1986 | +}; |
1987 | + |
1988 | +} |
1989 | +} |
1990 | +} |
1991 | + |
1992 | +#endif // MIR_INPUT_X_INPUT_PLATFORM_H_ |
1993 | |
1994 | === added file 'src/platforms/mesa/server/x11/platform.cpp' |
1995 | --- src/platforms/mesa/server/x11/platform.cpp 1970-01-01 00:00:00 +0000 |
1996 | +++ src/platforms/mesa/server/x11/platform.cpp 2015-07-22 20:26:39 +0000 |
1997 | @@ -0,0 +1,135 @@ |
1998 | +/* |
1999 | + * Copyright © 2015 Canonical Ltd. |
2000 | + * |
2001 | + * This program is free software: you can redistribute it and/or modify it |
2002 | + * under the terms of the GNU Lesser General Public License version 3, |
2003 | + * as published by the Free Software Foundation. |
2004 | + * |
2005 | + * This program is distributed in the hope that it will be useful, |
2006 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2007 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2008 | + * GNU Lesser General Public License for more details. |
2009 | + * |
2010 | + * You should have received a copy of the GNU Lesser General Public License |
2011 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2012 | + * |
2013 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
2014 | + */ |
2015 | + |
2016 | +#include "platform.h" |
2017 | +#include "display.h" |
2018 | +#include "buffer_allocator.h" |
2019 | +#include "ipc_operations.h" |
2020 | +#include "xserver_connection.h" |
2021 | +#include "mir/udev/wrapper.h" |
2022 | + |
2023 | +#include <boost/throw_exception.hpp> |
2024 | + |
2025 | +namespace mg = mir::graphics; |
2026 | +namespace mgm = mg::mesa; |
2027 | +namespace mgx = mg::X; |
2028 | +namespace mo = mir::options; |
2029 | +namespace mx = mir::X; |
2030 | + |
2031 | +//TODO: Remove this global by allowing input and graphics drivers to share |
2032 | +// some context like the x11 display handle. |
2033 | +std::shared_ptr<mx::X11Connection> x11_connection; |
2034 | + |
2035 | +mgx::Platform::Platform() |
2036 | + : udev{std::make_shared<mir::udev::Context>()}, |
2037 | + drm{std::make_shared<mesa::helpers::DRMHelper>(mesa::helpers::DRMNodeToUse::render)} |
2038 | +{ |
2039 | + if (x11_connection) |
2040 | + BOOST_THROW_EXCEPTION(std::runtime_error("Cannot create x11 platform more than once")); |
2041 | + |
2042 | + x11_connection.reset(new mx::X11Connection()); |
2043 | + |
2044 | + if (!x11_connection->dpy) |
2045 | + BOOST_THROW_EXCEPTION(std::runtime_error("Cannot open x11 display")); |
2046 | + |
2047 | + drm->setup(udev); |
2048 | + gbm.setup(*drm); |
2049 | +} |
2050 | + |
2051 | +std::shared_ptr<mg::GraphicBufferAllocator> mgx::Platform::create_buffer_allocator() |
2052 | +{ |
2053 | + return std::make_shared<mgm::BufferAllocator>(gbm.device, mgm::BypassOption::prohibited, mgm::BufferImportMethod::dma_buf); |
2054 | +} |
2055 | + |
2056 | +std::shared_ptr<mg::Display> mgx::Platform::create_display( |
2057 | + std::shared_ptr<DisplayConfigurationPolicy> const& /*initial_conf_policy*/, |
2058 | + std::shared_ptr<GLProgramFactory> const&, |
2059 | + std::shared_ptr<GLConfig> const& /*gl_config*/) |
2060 | +{ |
2061 | + return std::make_shared<mgx::Display>(x11_connection->dpy); |
2062 | +} |
2063 | + |
2064 | +std::shared_ptr<mg::PlatformIpcOperations> mgx::Platform::make_ipc_operations() const |
2065 | +{ |
2066 | + return std::make_shared<mg::mesa::IpcOperations>(drm); |
2067 | +} |
2068 | + |
2069 | +EGLNativeDisplayType mgx::Platform::egl_native_display() const |
2070 | +{ |
2071 | + return eglGetDisplay(x11_connection->dpy); |
2072 | +} |
2073 | + |
2074 | +//////////////////////////////////////////////////////////////////////////////////// |
2075 | +// Platform module entry points below |
2076 | +//////////////////////////////////////////////////////////////////////////////////// |
2077 | + |
2078 | +std::shared_ptr<mg::Platform> create_host_platform( |
2079 | + std::shared_ptr<mo::Option> const& /*options*/, |
2080 | + std::shared_ptr<mir::EmergencyCleanupRegistry> const& /*emergency_cleanup_registry*/, |
2081 | + std::shared_ptr<mg::DisplayReport> const& /*report*/) |
2082 | +{ |
2083 | + return std::make_shared<mgx::Platform>(); |
2084 | +} |
2085 | + |
2086 | +std::shared_ptr<mg::Platform> create_guest_platform( |
2087 | + std::shared_ptr<mg::DisplayReport> const& /*report*/, |
2088 | + std::shared_ptr<mg::NestedContext> const&) |
2089 | +{ |
2090 | + BOOST_THROW_EXCEPTION(std::runtime_error("Guest platform isn't supported under X")); |
2091 | + return nullptr; |
2092 | +} |
2093 | + |
2094 | +void add_graphics_platform_options(boost::program_options::options_description& /*config*/) |
2095 | +{ |
2096 | +} |
2097 | + |
2098 | +mg::PlatformPriority probe_graphics_platform(mo::ProgramOption const& /*options*/) |
2099 | +{ |
2100 | + auto dpy = XOpenDisplay(nullptr); |
2101 | + if (dpy) |
2102 | + { |
2103 | + XCloseDisplay(dpy); |
2104 | + |
2105 | + auto udev = std::make_shared<mir::udev::Context>(); |
2106 | + |
2107 | + mir::udev::Enumerator drm_devices{udev}; |
2108 | + drm_devices.match_subsystem("drm"); |
2109 | + drm_devices.match_sysname("renderD[0-9]*"); |
2110 | + drm_devices.scan_devices(); |
2111 | + |
2112 | + for (auto& device : drm_devices) |
2113 | + { |
2114 | + static_cast<void>(device); |
2115 | + |
2116 | + return mg::PlatformPriority::best; |
2117 | + } |
2118 | + } |
2119 | + return mg::PlatformPriority::unsupported; |
2120 | +} |
2121 | + |
2122 | +mir::ModuleProperties const description = { |
2123 | + "mesa-x11", |
2124 | + MIR_VERSION_MAJOR, |
2125 | + MIR_VERSION_MINOR, |
2126 | + MIR_VERSION_MICRO |
2127 | +}; |
2128 | + |
2129 | +mir::ModuleProperties const* describe_graphics_module() |
2130 | +{ |
2131 | + return &description; |
2132 | +} |
2133 | |
2134 | === added file 'src/platforms/mesa/server/x11/platform.h' |
2135 | --- src/platforms/mesa/server/x11/platform.h 1970-01-01 00:00:00 +0000 |
2136 | +++ src/platforms/mesa/server/x11/platform.h 2015-07-22 20:26:39 +0000 |
2137 | @@ -0,0 +1,61 @@ |
2138 | +/* |
2139 | + * Copyright © 2015 Canonical Ltd. |
2140 | + * |
2141 | + * This program is free software: you can redistribute it and/or modify it |
2142 | + * under the terms of the GNU Lesser General Public License version 3, |
2143 | + * as published by the Free Software Foundation. |
2144 | + * |
2145 | + * This program is distributed in the hope that it will be useful, |
2146 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2147 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2148 | + * GNU Lesser General Public License for more details. |
2149 | + * |
2150 | + * You should have received a copy of the GNU Lesser General Public License |
2151 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2152 | + * |
2153 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
2154 | + */ |
2155 | + |
2156 | +#ifndef MIR_GRAPHICS_X_PLATFORM_H_ |
2157 | +#define MIR_GRAPHICS_X_PLATFORM_H_ |
2158 | + |
2159 | +#include "mir/graphics/platform.h" |
2160 | +#include "display_helpers.h" |
2161 | + |
2162 | +#include <X11/Xlib.h> |
2163 | +#include <X11/Xutil.h> |
2164 | + |
2165 | +namespace mir |
2166 | +{ |
2167 | +namespace graphics |
2168 | +{ |
2169 | +namespace X |
2170 | +{ |
2171 | + |
2172 | +class Platform : public graphics::Platform |
2173 | +{ |
2174 | +public: |
2175 | + explicit Platform(); |
2176 | + ~Platform() = default; |
2177 | + |
2178 | + /* From Platform */ |
2179 | + std::shared_ptr<graphics::GraphicBufferAllocator> create_buffer_allocator() override; |
2180 | + |
2181 | + std::shared_ptr<graphics::Display> create_display( |
2182 | + std::shared_ptr<DisplayConfigurationPolicy> const& initial_conf_policy, |
2183 | + std::shared_ptr<GLProgramFactory> const& program_factory, |
2184 | + std::shared_ptr<GLConfig> const& gl_config) override; |
2185 | + |
2186 | + std::shared_ptr<PlatformIpcOperations> make_ipc_operations() const override; |
2187 | + |
2188 | + EGLNativeDisplayType egl_native_display() const override; |
2189 | +private: |
2190 | + std::shared_ptr<mir::udev::Context> udev; |
2191 | + std::shared_ptr<mesa::helpers::DRMHelper> const drm; |
2192 | + mesa::helpers::GBMHelper gbm; |
2193 | +}; |
2194 | + |
2195 | +} |
2196 | +} |
2197 | +} |
2198 | +#endif /* MIR_GRAPHICS_X_PLATFORM_H_ */ |
2199 | |
2200 | === added file 'src/platforms/mesa/server/x11/symbols.map' |
2201 | --- src/platforms/mesa/server/x11/symbols.map 1970-01-01 00:00:00 +0000 |
2202 | +++ src/platforms/mesa/server/x11/symbols.map 2015-07-22 20:26:39 +0000 |
2203 | @@ -0,0 +1,18 @@ |
2204 | +MIR_GRAPHICS_PLATFORM_4 { |
2205 | + global: |
2206 | + add_graphics_platform_options; |
2207 | + probe_graphics_platform; |
2208 | + create_host_platform; |
2209 | + create_guest_platform; |
2210 | + describe_graphics_module; |
2211 | + local: *; |
2212 | +}; |
2213 | + |
2214 | +MIR_INPUT_PLATFORM_1 { |
2215 | + global: |
2216 | + add_input_platform_options; |
2217 | + create_input_platform; |
2218 | + probe_input_platform; |
2219 | + describe_input_module; |
2220 | + local: *; |
2221 | +}; |
2222 | |
2223 | === added file 'src/platforms/mesa/server/x11/xserver_connection.h' |
2224 | --- src/platforms/mesa/server/x11/xserver_connection.h 1970-01-01 00:00:00 +0000 |
2225 | +++ src/platforms/mesa/server/x11/xserver_connection.h 2015-07-22 20:26:39 +0000 |
2226 | @@ -0,0 +1,47 @@ |
2227 | +/* |
2228 | + * Copyright © 2015 Canonical Ltd. |
2229 | + * |
2230 | + * This program is free software: you can redistribute it and/or modify it |
2231 | + * under the terms of the GNU Lesser General Public License version 3, |
2232 | + * as published by the Free Software Foundation. |
2233 | + * |
2234 | + * This program is distributed in the hope that it will be useful, |
2235 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2236 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2237 | + * GNU Lesser General Public License for more details. |
2238 | + * |
2239 | + * You should have received a copy of the GNU Lesser General Public License |
2240 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2241 | + * |
2242 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
2243 | + */ |
2244 | + |
2245 | +#ifndef MIR_X_XSERVER_CONNECTION_H_ |
2246 | +#define MIR_X_XSERVER_CONNECTION_H_ |
2247 | + |
2248 | +#include <X11/Xlib.h> |
2249 | +#include <X11/Xutil.h> |
2250 | + |
2251 | +namespace mir |
2252 | +{ |
2253 | +namespace X |
2254 | +{ |
2255 | + |
2256 | +struct X11Connection |
2257 | +{ |
2258 | + X11Connection() |
2259 | + { |
2260 | + dpy = XOpenDisplay(nullptr); |
2261 | + } |
2262 | + |
2263 | + ~X11Connection() |
2264 | + { |
2265 | + XCloseDisplay(dpy); |
2266 | + } |
2267 | + |
2268 | + ::Display *dpy; |
2269 | +}; |
2270 | + |
2271 | +} |
2272 | +} |
2273 | +#endif /* MIR_X_XSERVER_CONNECTION_H_ */ |
2274 | |
2275 | === modified file 'tests/CMakeLists.txt' |
2276 | --- tests/CMakeLists.txt 2015-06-29 03:29:31 +0000 |
2277 | +++ tests/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2278 | @@ -33,6 +33,10 @@ |
2279 | add_definitions(-DMESA_KMS) |
2280 | endif() |
2281 | |
2282 | +if (MIR_TEST_PLATFORM STREQUAL "mesa-x11") |
2283 | + add_definitions(-DMESA_X11) |
2284 | +endif() |
2285 | + |
2286 | if (MIR_BUILD_PLATFORM_ANDROID) |
2287 | #avoid complaints about poor quality android headers |
2288 | include_directories(SYSTEM ${LIBHARDWARE_INCLUDE_DIRS}) |
2289 | |
2290 | === modified file 'tests/acceptance-tests/test_client_library.cpp' |
2291 | --- tests/acceptance-tests/test_client_library.cpp 2015-07-16 07:03:19 +0000 |
2292 | +++ tests/acceptance-tests/test_client_library.cpp 2015-07-22 20:26:39 +0000 |
2293 | @@ -421,7 +421,7 @@ |
2294 | } |
2295 | #endif |
2296 | |
2297 | -#ifdef ANDROID |
2298 | +#if defined(ANDROID) || defined(MESA_X11) |
2299 | // Mir's Android test infrastructure isn't quite ready for this yet. |
2300 | TEST_F(ClientLibrary, DISABLED_gets_buffer_dimensions) |
2301 | #else |
2302 | @@ -646,10 +646,10 @@ |
2303 | * trying to marshall stub buffers causes crashes. |
2304 | */ |
2305 | |
2306 | -#ifndef ANDROID |
2307 | +#if defined(ANDROID) || defined(MESA_X11) |
2308 | +TEST_F(ClientLibrary, DISABLED_create_simple_normal_surface_from_spec) |
2309 | +#else |
2310 | TEST_F(ClientLibrary, create_simple_normal_surface_from_spec) |
2311 | -#else |
2312 | -TEST_F(ClientLibrary, DISABLED_create_simple_normal_surface_from_spec) |
2313 | #endif |
2314 | { |
2315 | auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__); |
2316 | @@ -677,10 +677,10 @@ |
2317 | mir_connection_release(connection); |
2318 | } |
2319 | |
2320 | -#ifndef ANDROID |
2321 | +#if defined(ANDROID) || defined(MESA_X11) |
2322 | +TEST_F(ClientLibrary, DISABLED_create_simple_normal_surface_from_spec_async) |
2323 | +#else |
2324 | TEST_F(ClientLibrary, create_simple_normal_surface_from_spec_async) |
2325 | -#else |
2326 | -TEST_F(ClientLibrary, DISABLED_create_simple_normal_surface_from_spec_async) |
2327 | #endif |
2328 | { |
2329 | auto connection = mir_connect_sync(new_connection().c_str(), __PRETTY_FUNCTION__); |
2330 | @@ -744,10 +744,10 @@ |
2331 | mir_connection_release(connection); |
2332 | } |
2333 | |
2334 | -#ifndef ANDROID |
2335 | +#if defined(ANDROID) || defined(MESA_X11) |
2336 | +TEST_F(ClientLibrary, DISABLED_set_fullscreen_on_output_makes_fullscreen_surface) |
2337 | +#else |
2338 | TEST_F(ClientLibrary, set_fullscreen_on_output_makes_fullscreen_surface) |
2339 | -#else |
2340 | -TEST_F(ClientLibrary, DISABLED_set_fullscreen_on_output_makes_fullscreen_surface) |
2341 | #endif |
2342 | { |
2343 | using namespace testing; |
2344 | |
2345 | === added file 'tests/include/mir/test/doubles/mock_input_sink.h' |
2346 | --- tests/include/mir/test/doubles/mock_input_sink.h 1970-01-01 00:00:00 +0000 |
2347 | +++ tests/include/mir/test/doubles/mock_input_sink.h 2015-07-22 20:26:39 +0000 |
2348 | @@ -0,0 +1,44 @@ |
2349 | +/* |
2350 | + * Copyright © 2015 Canonical Ltd. |
2351 | + * |
2352 | + * This program is free software: you can redistribute it and/or modify it |
2353 | + * under the terms of the GNU General Public License version 3, |
2354 | + * as published by the Free Software Foundation. |
2355 | + * |
2356 | + * This program is distributed in the hope that it will be useful, |
2357 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2358 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2359 | + * GNU General Public License for more details. |
2360 | + * |
2361 | + * You should have received a copy of the GNU General Public License |
2362 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2363 | + * |
2364 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
2365 | + */ |
2366 | + |
2367 | +#ifndef MIR_TEST_DOUBLES_MOCK_INPUT_SINK_H_ |
2368 | +#define MIR_TEST_DOUBLES_MOCK_INPUT_SINK_H_ |
2369 | + |
2370 | +#include "mir/input/input_sink.h" |
2371 | + |
2372 | +#include <gmock/gmock.h> |
2373 | + |
2374 | +namespace mir |
2375 | +{ |
2376 | +namespace test |
2377 | +{ |
2378 | +namespace doubles |
2379 | +{ |
2380 | + |
2381 | +struct MockInputSink : mir::input::InputSink |
2382 | +{ |
2383 | + MOCK_METHOD1(handle_input, void(MirEvent&)); |
2384 | + MOCK_METHOD1(confine_pointer, void(mir::geometry::Point&)); |
2385 | + MOCK_CONST_METHOD0(bounding_rectangle, mir::geometry::Rectangle()); |
2386 | +}; |
2387 | + |
2388 | +} |
2389 | +} |
2390 | +} |
2391 | + |
2392 | +#endif // MIR_TEST_DOUBLES_MOCK_INPUT_SINK_H_ |
2393 | |
2394 | === added file 'tests/include/mir/test/doubles/mock_x11.h' |
2395 | --- tests/include/mir/test/doubles/mock_x11.h 1970-01-01 00:00:00 +0000 |
2396 | +++ tests/include/mir/test/doubles/mock_x11.h 2015-07-22 20:26:39 +0000 |
2397 | @@ -0,0 +1,78 @@ |
2398 | +/* |
2399 | + * Copyright © 2015 Canonical Ltd. |
2400 | + * |
2401 | + * This program is free software: you can redistribute it and/or modify |
2402 | + * it under the terms of the GNU General Public License version 3 as |
2403 | + * published by the Free Software Foundation. |
2404 | + * |
2405 | + * This program is distributed in the hope that it will be useful, |
2406 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2407 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2408 | + * GNU General Public License for more details. |
2409 | + * |
2410 | + * You should have received a copy of the GNU General Public License |
2411 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2412 | + * |
2413 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
2414 | + */ |
2415 | + |
2416 | +#ifndef MIR_TEST_DOUBLES_MOCK_X11_H_ |
2417 | +#define MIR_TEST_DOUBLES_MOCK_X11_H_ |
2418 | + |
2419 | +#include <gmock/gmock.h> |
2420 | + |
2421 | +#include <X11/Xlib.h> |
2422 | +#include <X11/Xutil.h> |
2423 | + |
2424 | +namespace mir |
2425 | +{ |
2426 | +namespace test |
2427 | +{ |
2428 | +namespace doubles |
2429 | +{ |
2430 | + |
2431 | +class FakeX11Resources |
2432 | +{ |
2433 | +public: |
2434 | + FakeX11Resources(); |
2435 | + ~FakeX11Resources() = default; |
2436 | + |
2437 | + Display *display; |
2438 | + Window window; |
2439 | + XVisualInfo visual_info; |
2440 | + XEvent event_return; |
2441 | +}; |
2442 | + |
2443 | +class MockX11 |
2444 | +{ |
2445 | +public: |
2446 | + MockX11(); |
2447 | + ~MockX11(); |
2448 | + |
2449 | + MOCK_METHOD1(XOpenDisplay, Display*(const char*)); |
2450 | + MOCK_METHOD1(XCloseDisplay, int(Display*)); |
2451 | + MOCK_METHOD4(XGetVisualInfo, XVisualInfo*(Display*, long, XVisualInfo*, int*)); |
2452 | + MOCK_METHOD4(XCreateColormap, Colormap(Display*, Window, Visual*, int)); |
2453 | + /* Too long to mock, use wrapper instead. |
2454 | + MOCK_METHOD12(XCreateWindow, Window(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*)); |
2455 | + */ |
2456 | + MOCK_METHOD10(XCreateWindow_wrapper, Window(Display*, Window, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*)); |
2457 | + MOCK_METHOD3(XSetNormalHints, int(Display*, Window, XSizeHints*)); |
2458 | + MOCK_METHOD8(XSetStandardProperties, int(Display*, Window, const char*, const char*, Pixmap, char **, int, XSizeHints*)); |
2459 | + MOCK_METHOD1(XFree, int(void*)); |
2460 | + MOCK_METHOD2(XMapWindow, int(Display*, Window)); |
2461 | + MOCK_METHOD2(XDestroyWindow, int(Display*, Window)); |
2462 | + MOCK_METHOD1(XConnectionNumber, int(Display*)); |
2463 | + MOCK_METHOD2(XNextEvent, int(Display*, XEvent*)); |
2464 | + MOCK_METHOD5(XLookupString, int(XKeyEvent*, char*, int, KeySym*, XComposeStatus*)); |
2465 | + MOCK_METHOD1(XRefreshKeyboardMapping, int(XMappingEvent*)); |
2466 | + MOCK_METHOD1(XDefaultRootWindow, Window(Display*)); |
2467 | + |
2468 | + FakeX11Resources fake_x11; |
2469 | +}; |
2470 | + |
2471 | +} |
2472 | +} |
2473 | +} |
2474 | + |
2475 | +#endif /* MIR_TEST_DOUBLES_MOCK_X11_H_ */ |
2476 | |
2477 | === modified file 'tests/mir_test_doubles/CMakeLists.txt' |
2478 | --- tests/mir_test_doubles/CMakeLists.txt 2015-06-26 08:00:59 +0000 |
2479 | +++ tests/mir_test_doubles/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2480 | @@ -28,6 +28,12 @@ |
2481 | ${CMAKE_CURRENT_SOURCE_DIR}/mock_gl.cpp |
2482 | ) |
2483 | |
2484 | +if (MIR_BUILD_PLATFORM_MESA_X11) |
2485 | + list(APPEND MIR_TEST_DOUBLES_PLATFORM_SRCS |
2486 | + ${CMAKE_CURRENT_SOURCE_DIR}/mock_x11.cpp |
2487 | + ) |
2488 | +endif() |
2489 | + |
2490 | if (MIR_BUILD_PLATFORM_MESA_KMS) |
2491 | include_directories( |
2492 | ${PROJECT_SOURCE_DIR}/src/platforms/mesa/server/common |
2493 | |
2494 | === added file 'tests/mir_test_doubles/mock_x11.cpp' |
2495 | --- tests/mir_test_doubles/mock_x11.cpp 1970-01-01 00:00:00 +0000 |
2496 | +++ tests/mir_test_doubles/mock_x11.cpp 2015-07-22 20:26:39 +0000 |
2497 | @@ -0,0 +1,133 @@ |
2498 | +/* |
2499 | + * Copyright © 2015 Canonical Ltd. |
2500 | + * |
2501 | + * This program is free software: you can redistribute it and/or modify |
2502 | + * it under the terms of the GNU General Public License version 3 as |
2503 | + * published by the Free Software Foundation. |
2504 | + * |
2505 | + * This program is distributed in the hope that it will be useful, |
2506 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2507 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2508 | + * GNU General Public License for more details. |
2509 | + * |
2510 | + * You should have received a copy of the GNU General Public License |
2511 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2512 | + * |
2513 | + * Authored by: |
2514 | + * Cemil Azizoglu <cemil.azizoglu@canonical.com> |
2515 | + */ |
2516 | + |
2517 | +#include "mir/test/doubles/mock_x11.h" |
2518 | +#include <gtest/gtest.h> |
2519 | + |
2520 | +namespace mtd=mir::test::doubles; |
2521 | + |
2522 | +namespace |
2523 | +{ |
2524 | +mtd::MockX11* global_mock = nullptr; |
2525 | +} |
2526 | + |
2527 | +mtd::FakeX11Resources::FakeX11Resources() |
2528 | + : display{reinterpret_cast<Display*>(0x12345678)}, |
2529 | + window{reinterpret_cast<Window>((long unsigned int)9876543210)} |
2530 | +{ |
2531 | + visual_info.depth=24; |
2532 | + event_return.type = KeyPress; |
2533 | +} |
2534 | + |
2535 | +mtd::MockX11::MockX11() |
2536 | +{ |
2537 | + using namespace testing; |
2538 | + assert(global_mock == nullptr && "Only one mock object per process is allowed"); |
2539 | + |
2540 | + global_mock = this; |
2541 | + |
2542 | + ON_CALL(*this, XOpenDisplay(_)) |
2543 | + .WillByDefault(Return(fake_x11.display)); |
2544 | + |
2545 | + ON_CALL(*this, XGetVisualInfo(fake_x11.display,_,_,_)) |
2546 | + .WillByDefault(Return(&fake_x11.visual_info)); |
2547 | + |
2548 | + ON_CALL(*this, XCreateWindow_wrapper(fake_x11.display,_,_,_,_,_,_,_,_,_)) |
2549 | + .WillByDefault(Return(fake_x11.window)); |
2550 | +} |
2551 | + |
2552 | +mtd::MockX11::~MockX11() |
2553 | +{ |
2554 | + global_mock = nullptr; |
2555 | +} |
2556 | + |
2557 | +Display *XOpenDisplay(const char *display_name) |
2558 | +{ |
2559 | + return global_mock->XOpenDisplay(display_name); |
2560 | +} |
2561 | + |
2562 | +int XCloseDisplay(Display *display) |
2563 | +{ |
2564 | + return global_mock->XCloseDisplay(display); |
2565 | +} |
2566 | + |
2567 | +XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return) |
2568 | +{ |
2569 | + return global_mock->XGetVisualInfo(display, vinfo_mask, vinfo_template, nitems_return); |
2570 | +} |
2571 | + |
2572 | +Colormap XCreateColormap(Display *display, Window w, Visual *visual, int alloc) |
2573 | +{ |
2574 | + return global_mock->XCreateColormap(display, w, visual, alloc); |
2575 | +} |
2576 | + |
2577 | +Window XCreateWindow(Display * display, Window parent, int /*x*/, int /*y*/, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clss, Visual *visual, unsigned long valuemask, XSetWindowAttributes *attributes) |
2578 | +{ |
2579 | + return global_mock->XCreateWindow_wrapper(display, parent, width, height, border_width, depth, clss, visual, valuemask, attributes); |
2580 | +} |
2581 | + |
2582 | +int XSetNormalHints(Display *display, Window w, XSizeHints *hints) |
2583 | +{ |
2584 | + return global_mock->XSetNormalHints(display, w, hints); |
2585 | +} |
2586 | + |
2587 | +int XSetStandardProperties(Display *display, Window w, const char *window_name, const char *icon_name, Pixmap icon_pixmap, char **argv, int argc, XSizeHints *hints) |
2588 | +{ |
2589 | + return global_mock->XSetStandardProperties(display, w, window_name, icon_name, icon_pixmap, argv, argc, hints); |
2590 | +} |
2591 | + |
2592 | +int XFree(void *data) |
2593 | +{ |
2594 | + return global_mock->XFree(data); |
2595 | +} |
2596 | + |
2597 | +int XMapWindow(Display *display, Window w) |
2598 | +{ |
2599 | + return global_mock->XMapWindow(display, w); |
2600 | +} |
2601 | + |
2602 | +int XDestroyWindow(Display *display, Window w) |
2603 | +{ |
2604 | + return global_mock->XDestroyWindow(display, w); |
2605 | +} |
2606 | + |
2607 | +int XConnectionNumber(Display *display) |
2608 | +{ |
2609 | + return global_mock->XConnectionNumber(display); |
2610 | +} |
2611 | + |
2612 | +int XNextEvent(Display *display, XEvent *event_return) |
2613 | +{ |
2614 | + return global_mock->XNextEvent(display, event_return); |
2615 | +} |
2616 | + |
2617 | +int XLookupString(XKeyEvent *event_struct, char *buffer_return, int bytes_buffer, KeySym *keysym_return, XComposeStatus *status_in_out) |
2618 | +{ |
2619 | + return global_mock->XLookupString(event_struct, buffer_return, bytes_buffer, keysym_return, status_in_out); |
2620 | +} |
2621 | + |
2622 | +int XRefreshKeyboardMapping(XMappingEvent *event_map) |
2623 | +{ |
2624 | + return global_mock->XRefreshKeyboardMapping(event_map); |
2625 | +} |
2626 | + |
2627 | +Window XDefaultRootWindow(Display *display) |
2628 | +{ |
2629 | + return global_mock->XDefaultRootWindow(display); |
2630 | +} |
2631 | |
2632 | === modified file 'tests/mir_test_doubles/platform_factory.cpp' |
2633 | --- tests/mir_test_doubles/platform_factory.cpp 2015-06-25 21:34:27 +0000 |
2634 | +++ tests/mir_test_doubles/platform_factory.cpp 2015-07-22 20:26:39 +0000 |
2635 | @@ -22,6 +22,8 @@ |
2636 | |
2637 | #ifdef MESA_KMS |
2638 | #include "src/platforms/mesa/server/kms/platform.h" |
2639 | +#elif MESA_X11 |
2640 | +#include "src/platforms/mesa/server/x11/platform.h" |
2641 | #endif |
2642 | |
2643 | #include "src/server/report/null_report_factory.h" |
2644 | @@ -41,7 +43,7 @@ |
2645 | report::null_display_report()); |
2646 | } |
2647 | |
2648 | -#else |
2649 | +#elif MESA_KMS |
2650 | auto mtd::create_platform_with_null_dependencies() |
2651 | -> std::shared_ptr<graphics::Platform> |
2652 | { |
2653 | @@ -57,4 +59,10 @@ |
2654 | *std::make_shared<NullEmergencyCleanup>(), |
2655 | graphics::mesa::BypassOption::allowed); |
2656 | } |
2657 | +#elif MESA_X11 |
2658 | +auto mtd::create_platform_with_null_dependencies() |
2659 | + -> std::shared_ptr<graphics::Platform> |
2660 | +{ |
2661 | + return std::make_shared<graphics::X::Platform>(); |
2662 | +} |
2663 | #endif |
2664 | |
2665 | === modified file 'tests/mir_test_doubles/stub_buffer.cpp' |
2666 | --- tests/mir_test_doubles/stub_buffer.cpp 2015-06-25 21:34:27 +0000 |
2667 | +++ tests/mir_test_doubles/stub_buffer.cpp 2015-07-22 20:26:39 +0000 |
2668 | @@ -20,7 +20,7 @@ |
2669 | |
2670 | #ifdef ANDROID |
2671 | #include "mir/test/doubles/stub_android_native_buffer.h" |
2672 | -#else |
2673 | +#elif defined(MESA_KMS) || defined(MESA_X11) |
2674 | #include "mir/test/doubles/stub_gbm_native_buffer.h" |
2675 | #endif |
2676 | |
2677 | @@ -29,9 +29,9 @@ |
2678 | auto mtd::StubBuffer::create_native_buffer() |
2679 | -> std::shared_ptr<graphics::NativeBuffer> |
2680 | { |
2681 | -#ifdef MESA_KMS |
2682 | +#if defined(MESA_KMS) || defined(MESA_X11) |
2683 | return std::make_shared<StubGBMNativeBuffer>(geometry::Size{0,0}); |
2684 | -#else |
2685 | +#elif ANDROID |
2686 | return std::make_shared<StubAndroidNativeBuffer>(); |
2687 | #endif |
2688 | } |
2689 | |
2690 | === modified file 'tests/mir_test_framework/stubbed_graphics_platform.cpp' |
2691 | --- tests/mir_test_framework/stubbed_graphics_platform.cpp 2015-07-16 07:03:19 +0000 |
2692 | +++ tests/mir_test_framework/stubbed_graphics_platform.cpp 2015-07-22 20:26:39 +0000 |
2693 | @@ -65,7 +65,7 @@ |
2694 | |
2695 | std::shared_ptr<mg::NativeBuffer> native_buffer_handle() const override |
2696 | { |
2697 | -#ifdef MESA_KMS |
2698 | +#if defined(MESA_KMS) || defined(MESA_X11) |
2699 | auto native_buffer = std::make_shared<mg::NativeBuffer>(); |
2700 | native_buffer->data_items = 1; |
2701 | native_buffer->data[0] = 0xDEADBEEF; |
2702 | @@ -124,7 +124,7 @@ |
2703 | { |
2704 | if (msg_type == mg::BufferIpcMsgType::full_msg) |
2705 | { |
2706 | -#ifdef MESA_KMS |
2707 | +#if defined(MESA_KMS) || defined(MESA_X11) |
2708 | auto native_handle = buffer.native_buffer_handle(); |
2709 | for(auto i=0; i<native_handle->data_items; i++) |
2710 | { |
2711 | |
2712 | === modified file 'tests/unit-tests/CMakeLists.txt' |
2713 | --- tests/unit-tests/CMakeLists.txt 2015-07-14 07:28:55 +0000 |
2714 | +++ tests/unit-tests/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2715 | @@ -23,6 +23,7 @@ |
2716 | ${PROJECT_SOURCE_DIR}/src/include/client |
2717 | ${PROJECT_SOURCE_DIR}/src/include/common |
2718 | ${PROJECT_SOURCE_DIR}/src/platforms/common/client |
2719 | + ${PROJECT_SOURCE_DIR}/src/platforms/mesa/server/common |
2720 | ${GLIB_INCLUDE_DIRS} |
2721 | ) |
2722 | |
2723 | @@ -61,6 +62,12 @@ |
2724 | test_module_deleter.cpp |
2725 | ) |
2726 | |
2727 | +if (MIR_TEST_PLATFORM STREQUAL "mesa-x11") |
2728 | +list(APPEND UNIT_TEST_SOURCES |
2729 | + $<TARGET_OBJECTS:mirplatformservermesax11objects> |
2730 | +) |
2731 | +endif() |
2732 | + |
2733 | add_subdirectory(options/) |
2734 | add_subdirectory(client/) |
2735 | add_subdirectory(compositor/) |
2736 | @@ -133,11 +140,10 @@ |
2737 | ${XKBCOMMON_LIBRARIES} |
2738 | ) |
2739 | |
2740 | -if (MIR_BUILD_PLATFORM_MESA_KMS) |
2741 | target_link_libraries(mir_unit_tests |
2742 | mirsharedmesaservercommon-static |
2743 | + ${DRM_LDFLAGS} ${DRM_LIBRARIES} |
2744 | ) |
2745 | -endif() |
2746 | |
2747 | if (MIR_BUILD_PLATFORM_ANDROID) |
2748 | target_link_libraries(mir_unit_tests |
2749 | |
2750 | === modified file 'tests/unit-tests/client/CMakeLists.txt' |
2751 | --- tests/unit-tests/client/CMakeLists.txt 2015-07-16 07:03:19 +0000 |
2752 | +++ tests/unit-tests/client/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2753 | @@ -23,7 +23,7 @@ |
2754 | add_subdirectory("android") |
2755 | endif() |
2756 | |
2757 | -if(MIR_TEST_PLATFORM STREQUAL "mesa-kms") |
2758 | +if(MIR_TEST_PLATFORM STREQUAL "mesa-kms" OR MIR_TEST_PLATFORM STREQUAL "mesa-x11" ) |
2759 | add_subdirectory("mesa") |
2760 | endif() |
2761 | |
2762 | |
2763 | === modified file 'tests/unit-tests/graphics/CMakeLists.txt' |
2764 | --- tests/unit-tests/graphics/CMakeLists.txt 2015-06-18 02:46:16 +0000 |
2765 | +++ tests/unit-tests/graphics/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2766 | @@ -1,9 +1,7 @@ |
2767 | list(APPEND UNIT_TEST_SOURCES |
2768 | - ${CMAKE_CURRENT_SOURCE_DIR}/test_graphics_platform.cpp |
2769 | ${CMAKE_CURRENT_SOURCE_DIR}/test_display_configuration.cpp |
2770 | ${CMAKE_CURRENT_SOURCE_DIR}/test_egl_extensions.cpp |
2771 | ${CMAKE_CURRENT_SOURCE_DIR}/test_egl_error.cpp |
2772 | - ${CMAKE_CURRENT_SOURCE_DIR}/test_display.cpp |
2773 | ${CMAKE_CURRENT_SOURCE_DIR}/test_default_display_configuration_policy.cpp |
2774 | ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_id.cpp |
2775 | ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_properties.cpp |
2776 | @@ -15,16 +13,23 @@ |
2777 | ${CMAKE_CURRENT_SOURCE_DIR}/test_software_cursor.cpp |
2778 | ) |
2779 | |
2780 | +if (MIR_TEST_PLATFORM STREQUAL "mesa-kms" OR MIR_TEST_PLATFORM STREQUAL "android") |
2781 | + list(APPEND UNIT_TEST_SOURCES |
2782 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_graphics_platform.cpp |
2783 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_display.cpp |
2784 | + ) |
2785 | +endif() |
2786 | + |
2787 | add_subdirectory(nested/) |
2788 | add_subdirectory(offscreen/) |
2789 | |
2790 | add_subdirectory(egl_mock/) |
2791 | if (MIR_TEST_PLATFORM STREQUAL "android") |
2792 | -add_subdirectory(android/) |
2793 | + add_subdirectory(android/) |
2794 | endif() |
2795 | |
2796 | -if (MIR_TEST_PLATFORM STREQUAL "mesa-kms") |
2797 | -add_subdirectory(mesa/) |
2798 | +if (MIR_TEST_PLATFORM STREQUAL "mesa-kms" OR MIR_TEST_PLATFORM STREQUAL "mesa-x11") |
2799 | + add_subdirectory(mesa/) |
2800 | endif() |
2801 | |
2802 | set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE) |
2803 | |
2804 | === modified file 'tests/unit-tests/graphics/mesa/CMakeLists.txt' |
2805 | --- tests/unit-tests/graphics/mesa/CMakeLists.txt 2015-06-19 01:35:28 +0000 |
2806 | +++ tests/unit-tests/graphics/mesa/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2807 | @@ -9,4 +9,8 @@ |
2808 | add_subdirectory(kms/) |
2809 | endif() |
2810 | |
2811 | +if (MIR_TEST_PLATFORM STREQUAL "mesa-x11") |
2812 | + add_subdirectory(x11/) |
2813 | +endif() |
2814 | + |
2815 | set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE) |
2816 | |
2817 | === modified file 'tests/unit-tests/graphics/mesa/common/CMakeLists.txt' |
2818 | --- tests/unit-tests/graphics/mesa/common/CMakeLists.txt 2015-06-18 10:00:46 +0000 |
2819 | +++ tests/unit-tests/graphics/mesa/common/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2820 | @@ -1,6 +1,4 @@ |
2821 | add_library(unit_test_graphics_mesa_common OBJECT |
2822 | - ${CMAKE_CURRENT_SOURCE_DIR}/test_gbm_buffer.cpp |
2823 | - ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_allocator.cpp |
2824 | ${CMAKE_CURRENT_SOURCE_DIR}/test_anonymous_shm_file.cpp |
2825 | ${CMAKE_CURRENT_SOURCE_DIR}/test_shm_buffer.cpp |
2826 | ${CMAKE_CURRENT_SOURCE_DIR}/test_drm_helper.cpp |
2827 | |
2828 | === modified file 'tests/unit-tests/graphics/mesa/common/test_drm_helper.cpp' |
2829 | --- tests/unit-tests/graphics/mesa/common/test_drm_helper.cpp 2015-06-26 08:00:59 +0000 |
2830 | +++ tests/unit-tests/graphics/mesa/common/test_drm_helper.cpp 2015-07-22 20:26:39 +0000 |
2831 | @@ -50,7 +50,7 @@ |
2832 | protected: |
2833 | ::testing::NiceMock<mtd::MockDRM> mock_drm; |
2834 | mtf::UdevEnvironment fake_devices; |
2835 | - mgm::helpers::DRMHelper drm_helper; |
2836 | + mgm::helpers::DRMHelper drm_helper{mgm::helpers::DRMNodeToUse::card}; |
2837 | }; |
2838 | |
2839 | } |
2840 | |
2841 | === modified file 'tests/unit-tests/graphics/mesa/kms/CMakeLists.txt' |
2842 | --- tests/unit-tests/graphics/mesa/kms/CMakeLists.txt 2015-06-18 10:00:46 +0000 |
2843 | +++ tests/unit-tests/graphics/mesa/kms/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2844 | @@ -1,4 +1,6 @@ |
2845 | add_library(unit_test_graphics_mesa_kms OBJECT |
2846 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_gbm_buffer.cpp |
2847 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_buffer_allocator.cpp |
2848 | ${CMAKE_CURRENT_SOURCE_DIR}/test_platform.cpp |
2849 | ${CMAKE_CURRENT_SOURCE_DIR}/test_display.cpp |
2850 | ${CMAKE_CURRENT_SOURCE_DIR}/test_display_buffer.cpp |
2851 | |
2852 | === renamed file 'tests/unit-tests/graphics/mesa/common/test_buffer_allocator.cpp' => 'tests/unit-tests/graphics/mesa/kms/test_buffer_allocator.cpp' |
2853 | --- tests/unit-tests/graphics/mesa/common/test_buffer_allocator.cpp 2015-07-21 04:11:10 +0000 |
2854 | +++ tests/unit-tests/graphics/mesa/kms/test_buffer_allocator.cpp 2015-07-22 20:26:39 +0000 |
2855 | @@ -63,7 +63,7 @@ |
2856 | |
2857 | platform = mtd::create_mesa_platform_with_null_dependencies(); |
2858 | allocator.reset(new mgm::BufferAllocator( |
2859 | - platform->gbm.device, mgm::BypassOption::allowed)); |
2860 | + platform->gbm.device, mgm::BypassOption::allowed, mgm::BufferImportMethod::gbm_native_pixmap)); |
2861 | } |
2862 | |
2863 | // Defaults |
2864 | @@ -145,7 +145,8 @@ |
2865 | |
2866 | mgm::BufferAllocator alloc( |
2867 | platform->gbm.device, |
2868 | - mgm::BypassOption::prohibited); |
2869 | + mgm::BypassOption::prohibited, |
2870 | + mgm::BufferImportMethod::gbm_native_pixmap); |
2871 | auto buf = alloc.alloc_buffer(properties); |
2872 | ASSERT_TRUE(buf.get() != NULL); |
2873 | EXPECT_FALSE(buf->native_buffer_handle()->flags & mir_buffer_flag_can_scanout); |
2874 | |
2875 | === renamed file 'tests/unit-tests/graphics/mesa/common/test_gbm_buffer.cpp' => 'tests/unit-tests/graphics/mesa/kms/test_gbm_buffer.cpp' |
2876 | --- tests/unit-tests/graphics/mesa/common/test_gbm_buffer.cpp 2015-06-26 08:00:59 +0000 |
2877 | +++ tests/unit-tests/graphics/mesa/kms/test_gbm_buffer.cpp 2015-07-22 20:26:39 +0000 |
2878 | @@ -72,7 +72,7 @@ |
2879 | |
2880 | platform = mtd::create_mesa_platform_with_null_dependencies(); |
2881 | |
2882 | - allocator.reset(new mgm::BufferAllocator(platform->gbm.device, mgm::BypassOption::allowed)); |
2883 | + allocator.reset(new mgm::BufferAllocator(platform->gbm.device, mgm::BypassOption::allowed, mgm::BufferImportMethod::gbm_native_pixmap)); |
2884 | } |
2885 | |
2886 | ::testing::NiceMock<mtd::MockDRM> mock_drm; |
2887 | |
2888 | === added directory 'tests/unit-tests/graphics/mesa/x11' |
2889 | === added file 'tests/unit-tests/graphics/mesa/x11/CMakeLists.txt' |
2890 | --- tests/unit-tests/graphics/mesa/x11/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
2891 | +++ tests/unit-tests/graphics/mesa/x11/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
2892 | @@ -0,0 +1,6 @@ |
2893 | +list(APPEND UNIT_TEST_SOURCES |
2894 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_platform.cpp |
2895 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_display.cpp |
2896 | +) |
2897 | + |
2898 | +set(UNIT_TEST_SOURCES ${UNIT_TEST_SOURCES} PARENT_SCOPE) |
2899 | |
2900 | === added file 'tests/unit-tests/graphics/mesa/x11/test_display.cpp' |
2901 | --- tests/unit-tests/graphics/mesa/x11/test_display.cpp 1970-01-01 00:00:00 +0000 |
2902 | +++ tests/unit-tests/graphics/mesa/x11/test_display.cpp 2015-07-22 20:26:39 +0000 |
2903 | @@ -0,0 +1,101 @@ |
2904 | +/* |
2905 | + * Copyright © 2015 Canonical Ltd. |
2906 | + * |
2907 | + * This program is free software: you can redistribute it and/or modify |
2908 | + * it under the terms of the GNU General Public License version 3 as |
2909 | + * published by the Free Software Foundation. |
2910 | + * |
2911 | + * This program is distributed in the hope that it will be useful, |
2912 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
2913 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2914 | + * GNU General Public License for more details. |
2915 | + * |
2916 | + * You should have received a copy of the GNU General Public License |
2917 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
2918 | + * |
2919 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
2920 | + */ |
2921 | +#include "src/platforms/mesa/server/x11/display.h" |
2922 | +#include "mir/test/doubles/mock_egl.h" |
2923 | +#include "mir/test/doubles/mock_x11.h" |
2924 | + |
2925 | +#include <gtest/gtest.h> |
2926 | +#include <gmock/gmock.h> |
2927 | + |
2928 | +namespace mg=mir::graphics; |
2929 | +namespace mgx=mg::X; |
2930 | +namespace mtd=mir::test::doubles; |
2931 | + |
2932 | +namespace |
2933 | +{ |
2934 | + |
2935 | +EGLint const window_width = 1280; |
2936 | +EGLint const window_height = 1024; |
2937 | + |
2938 | +class X11DisplayTest : public ::testing::Test |
2939 | +{ |
2940 | +public: |
2941 | + |
2942 | + X11DisplayTest() |
2943 | + { |
2944 | + using namespace testing; |
2945 | + EGLint const client_version = 2; |
2946 | + |
2947 | + ON_CALL(mock_egl, eglQueryContext(mock_egl.fake_egl_display, |
2948 | + mock_egl.fake_egl_context, |
2949 | + EGL_CONTEXT_CLIENT_VERSION, |
2950 | + _)) |
2951 | + .WillByDefault(DoAll(SetArgPointee<3>(client_version), |
2952 | + Return(EGL_TRUE))); |
2953 | + |
2954 | + ON_CALL(mock_egl, eglQuerySurface(mock_egl.fake_egl_display, |
2955 | + mock_egl.fake_egl_surface, |
2956 | + EGL_WIDTH, |
2957 | + _)) |
2958 | + .WillByDefault(DoAll(SetArgPointee<3>(window_width), |
2959 | + Return(EGL_TRUE))); |
2960 | + |
2961 | + ON_CALL(mock_egl, eglQuerySurface(mock_egl.fake_egl_display, |
2962 | + mock_egl.fake_egl_surface, |
2963 | + EGL_HEIGHT, |
2964 | + _)) |
2965 | + .WillByDefault(DoAll(SetArgPointee<3>(window_height), |
2966 | + Return(EGL_TRUE))); |
2967 | + |
2968 | + ON_CALL(mock_egl, eglGetConfigAttrib(mock_egl.fake_egl_display, |
2969 | + _, |
2970 | + _, |
2971 | + _)) |
2972 | + .WillByDefault(DoAll(SetArgPointee<3>(EGL_WINDOW_BIT), |
2973 | + Return(EGL_TRUE))); |
2974 | + } |
2975 | + |
2976 | + std::shared_ptr<mgx::Display> create_display() |
2977 | + { |
2978 | + return std::make_shared<mgx::Display>(mock_x11.fake_x11.display); |
2979 | + } |
2980 | + |
2981 | + ::testing::NiceMock<mtd::MockEGL> mock_egl; |
2982 | + ::testing::NiceMock<mtd::MockX11> mock_x11; |
2983 | +}; |
2984 | + |
2985 | +} |
2986 | + |
2987 | +TEST_F(X11DisplayTest, creates_display_successfully) |
2988 | +{ |
2989 | + using namespace testing; |
2990 | + |
2991 | + EXPECT_CALL(mock_egl, eglGetDisplay(mock_x11.fake_x11.display)) |
2992 | + .Times(Exactly(1)); |
2993 | + |
2994 | + EXPECT_CALL(mock_x11, XCreateWindow_wrapper(mock_x11.fake_x11.display,_, window_width, window_height,_,_,_,_,_,_)) |
2995 | + .Times(Exactly(1)); |
2996 | + |
2997 | + EXPECT_CALL(mock_egl, eglCreateContext(mock_egl.fake_egl_display,_, EGL_NO_CONTEXT,_)) |
2998 | + .Times(Exactly(1)); |
2999 | + |
3000 | + EXPECT_CALL(mock_egl, eglCreateWindowSurface(mock_egl.fake_egl_display,_, mock_x11.fake_x11.window, nullptr)) |
3001 | + .Times(Exactly(1)); |
3002 | + |
3003 | + auto display = create_display(); |
3004 | +} |
3005 | |
3006 | === added file 'tests/unit-tests/graphics/mesa/x11/test_platform.cpp' |
3007 | --- tests/unit-tests/graphics/mesa/x11/test_platform.cpp 1970-01-01 00:00:00 +0000 |
3008 | +++ tests/unit-tests/graphics/mesa/x11/test_platform.cpp 2015-07-22 20:26:39 +0000 |
3009 | @@ -0,0 +1,125 @@ |
3010 | +/* |
3011 | + * Copyright © 2015 Canonical Ltd. |
3012 | + * |
3013 | + * This program is free software: you can redistribute it and/or modify |
3014 | + * it under the terms of the GNU General Public License version 3 as |
3015 | + * published by the Free Software Foundation. |
3016 | + * |
3017 | + * This program is distributed in the hope that it will be useful, |
3018 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3019 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3020 | + * GNU General Public License for more details. |
3021 | + * |
3022 | + * You should have received a copy of the GNU General Public License |
3023 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3024 | + * |
3025 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
3026 | + */ |
3027 | + |
3028 | +#include "mir/options/program_option.h" |
3029 | +#include "src/platforms/mesa/server/x11/platform.h" |
3030 | + |
3031 | +#include "mir/test/doubles/platform_factory.h" |
3032 | +#include "mir/test/doubles/mock_drm.h" |
3033 | +#include "mir/test/doubles/mock_gbm.h" |
3034 | +#include "mir/test/doubles/mock_x11.h" |
3035 | +#include "mir/shared_library.h" |
3036 | +#include "mir_test_framework/executable_path.h" |
3037 | +#include "mir_test_framework/udev_environment.h" |
3038 | + |
3039 | +#include <gtest/gtest.h> |
3040 | +#include <gmock/gmock.h> |
3041 | + |
3042 | +namespace mg = mir::graphics; |
3043 | +namespace mtd = mir::test::doubles; |
3044 | +namespace mtf = mir_test_framework; |
3045 | + |
3046 | +namespace |
3047 | +{ |
3048 | +const char probe_platform[] = "probe_graphics_platform"; |
3049 | + |
3050 | +class X11GraphicsPlatformTest : public ::testing::Test |
3051 | +{ |
3052 | +public: |
3053 | + void SetUp() |
3054 | + { |
3055 | + ::testing::Mock::VerifyAndClearExpectations(&mock_drm); |
3056 | + ::testing::Mock::VerifyAndClearExpectations(&mock_gbm); |
3057 | + } |
3058 | + |
3059 | + std::shared_ptr<mg::Platform> create_platform() |
3060 | + { |
3061 | + return mtd::create_platform_with_null_dependencies(); |
3062 | + } |
3063 | + |
3064 | + ::testing::NiceMock<mtd::MockDRM> mock_drm; |
3065 | + ::testing::NiceMock<mtd::MockGBM> mock_gbm; |
3066 | + ::testing::NiceMock<mtd::MockX11> mock_x11; |
3067 | +}; |
3068 | +} |
3069 | + |
3070 | +TEST_F(X11GraphicsPlatformTest, failure_to_open_x11_display_results_in_an_error) |
3071 | +{ |
3072 | + using namespace ::testing; |
3073 | + |
3074 | + EXPECT_CALL(mock_x11, XOpenDisplay(_)) |
3075 | + .WillRepeatedly(Return(nullptr)); |
3076 | + |
3077 | + EXPECT_THROW({ create_platform(); }, std::exception); |
3078 | +} |
3079 | + |
3080 | +TEST_F(X11GraphicsPlatformTest, failure_to_open_drm_results_in_an_error) |
3081 | +{ |
3082 | + using namespace ::testing; |
3083 | + |
3084 | + EXPECT_CALL(mock_drm, open(_,_,_)) |
3085 | + .WillRepeatedly(Return(-1)); |
3086 | + |
3087 | + EXPECT_THROW({ create_platform(); }, std::exception); |
3088 | +} |
3089 | + |
3090 | +TEST_F(X11GraphicsPlatformTest, failure_to_create_gbm_device_results_in_an_error) |
3091 | +{ |
3092 | + using namespace ::testing; |
3093 | + |
3094 | + EXPECT_CALL(mock_gbm, gbm_create_device(mock_drm.fake_drm.fd())) |
3095 | + .WillRepeatedly(Return(nullptr)); |
3096 | + |
3097 | + EXPECT_THROW({ create_platform(); }, std::exception); |
3098 | +} |
3099 | + |
3100 | +TEST_F(X11GraphicsPlatformTest, probe_returns_unsupported_when_no_drm_udev_devices) |
3101 | +{ |
3102 | + mtf::UdevEnvironment udev_environment; |
3103 | + mir::options::ProgramOption options; |
3104 | + |
3105 | + mir::SharedLibrary platform_lib{mtf::server_platform("server-mesa-x11")}; |
3106 | + auto probe = platform_lib.load_function<mg::PlatformProbe>(probe_platform); |
3107 | + EXPECT_EQ(mg::PlatformPriority::unsupported, probe(options)); |
3108 | +} |
3109 | + |
3110 | +TEST_F(X11GraphicsPlatformTest, probe_returns_unsupported_when_x_cannot_open_display) |
3111 | +{ |
3112 | + using namespace ::testing; |
3113 | + |
3114 | + mir::options::ProgramOption options; |
3115 | + |
3116 | + EXPECT_CALL(mock_x11, XOpenDisplay(_)) |
3117 | + .WillRepeatedly(Return(nullptr)); |
3118 | + |
3119 | + mir::SharedLibrary platform_lib{mtf::server_platform("server-mesa-x11")}; |
3120 | + auto probe = platform_lib.load_function<mg::PlatformProbe>(probe_platform); |
3121 | + EXPECT_EQ(mg::PlatformPriority::unsupported, probe(options)); |
3122 | +} |
3123 | + |
3124 | +TEST_F(X11GraphicsPlatformTest, probe_returns_best_when_drm_render_nodes_exist) |
3125 | +{ |
3126 | + mtf::UdevEnvironment udev_environment; |
3127 | + mir::options::ProgramOption options; |
3128 | + |
3129 | + udev_environment.add_standard_device("standard-drm-render-nodes"); |
3130 | + |
3131 | + mir::SharedLibrary platform_lib{mtf::server_platform("server-mesa-x11")}; |
3132 | + auto probe = platform_lib.load_function<mg::PlatformProbe>(probe_platform); |
3133 | + EXPECT_EQ(mg::PlatformPriority::best, probe(options)); |
3134 | +} |
3135 | |
3136 | === modified file 'tests/unit-tests/input/CMakeLists.txt' |
3137 | --- tests/unit-tests/input/CMakeLists.txt 2015-06-30 23:23:17 +0000 |
3138 | +++ tests/unit-tests/input/CMakeLists.txt 2015-07-22 20:26:39 +0000 |
3139 | @@ -15,6 +15,12 @@ |
3140 | ${CMAKE_CURRENT_SOURCE_DIR}/test_validator.cpp |
3141 | ) |
3142 | |
3143 | +if (MIR_TEST_PLATFORM STREQUAL "mesa-x11") |
3144 | + list(APPEND UNIT_TEST_SOURCES |
3145 | + ${CMAKE_CURRENT_SOURCE_DIR}/test_x11_dispatchable.cpp |
3146 | + ) |
3147 | +endif() |
3148 | + |
3149 | set( |
3150 | UNIT_TEST_SOURCES |
3151 | ${UNIT_TEST_SOURCES} |
3152 | |
3153 | === added file 'tests/unit-tests/input/test_x11_dispatchable.cpp' |
3154 | --- tests/unit-tests/input/test_x11_dispatchable.cpp 1970-01-01 00:00:00 +0000 |
3155 | +++ tests/unit-tests/input/test_x11_dispatchable.cpp 2015-07-22 20:26:39 +0000 |
3156 | @@ -0,0 +1,68 @@ |
3157 | +/* |
3158 | + * Copyright © 2015 Canonical Ltd. |
3159 | + * |
3160 | + * This program is free software: you can redistribute it and/or modify |
3161 | + * it under the terms of the GNU General Public License version 3 as |
3162 | + * published by the Free Software Foundation. |
3163 | + * |
3164 | + * This program is distributed in the hope that it will be useful, |
3165 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
3166 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
3167 | + * GNU General Public License for more details. |
3168 | + * |
3169 | + * You should have received a copy of the GNU General Public License |
3170 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
3171 | + * |
3172 | + * Authored by: Cemil Azizoglu <cemil.azizoglu@canonical.com> |
3173 | + */ |
3174 | + |
3175 | +#include "mir/events/event_private.h" |
3176 | +#include "mir_toolkit/event.h" |
3177 | +#include "src/platforms/mesa/server/x11/input/dispatchable.h" |
3178 | +#include "src/platforms/mesa/server/x11/xserver_connection.h" |
3179 | +#include "mir/test/doubles/mock_input_sink.h" |
3180 | +#include "mir/test/doubles/mock_x11.h" |
3181 | + |
3182 | +#include <gtest/gtest.h> |
3183 | +#include <gmock/gmock.h> |
3184 | + |
3185 | +namespace mtd = mir::test::doubles; |
3186 | + |
3187 | +using namespace ::testing; |
3188 | + |
3189 | +extern std::shared_ptr<mir::X::X11Connection> x11_connection; |
3190 | + |
3191 | +namespace |
3192 | +{ |
3193 | + |
3194 | +struct X11DispatchableTest : ::testing::Test |
3195 | +{ |
3196 | + X11DispatchableTest() |
3197 | + { |
3198 | + // X11Connection freed in the (external) shared_ptr destruction. |
3199 | + x11_connection.reset(new mir::X::X11Connection()); |
3200 | + } |
3201 | + |
3202 | + ~X11DispatchableTest() |
3203 | + { |
3204 | + x11_connection.reset(); |
3205 | + } |
3206 | + |
3207 | + mir::input::X::XDispatchable x11_dispatchable{0}; |
3208 | + NiceMock<mtd::MockInputSink> mock_input_sink; |
3209 | + NiceMock<mtd::MockX11> mock_x11; |
3210 | +}; |
3211 | + |
3212 | +} |
3213 | + |
3214 | +TEST_F(X11DispatchableTest, dispatches_input_events_to_sink) |
3215 | +{ |
3216 | + ON_CALL(mock_x11, XNextEvent(_,_)) |
3217 | + .WillByDefault(DoAll(SetArgPointee<1>(mock_x11.fake_x11.event_return), |
3218 | + Return(1))); |
3219 | + |
3220 | + EXPECT_CALL(mock_input_sink, handle_input(_)); |
3221 | + |
3222 | + x11_dispatchable.set_input_sink(&mock_input_sink); |
3223 | + x11_dispatchable.dispatch(mir::dispatch::FdEvent::readable); |
3224 | +} |
FAILED: Continuous integration, rev:2673 jenkins. qa.ubuntu. com/job/ mir-ci/ 4193/ jenkins. qa.ubuntu. com/job/ mir-android- vivid-i386- build/2985 jenkins. qa.ubuntu. com/job/ mir-clang- wily-amd64- build/502 jenkins. qa.ubuntu. com/job/ mir-mediumtests -vivid- touch/2933/ console jenkins. qa.ubuntu. com/job/ mir-wily- amd64-ci/ 349 jenkins. qa.ubuntu. com/job/ mir-wily- amd64-ci/ 349/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 2933 jenkins. qa.ubuntu. com/job/ mir-mediumtests -builder- vivid-armhf/ 2933/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ mir-mediumtests -runner- mako/5752/ console s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 21464
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/mir- ci/4193/ rebuild
http://