-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Architecture diagram and description of the project's folders #3053
Changes from 16 commits
ef2f3a6
934d817
c18ea51
528b648
07d5e06
2a8ae74
a7f49a5
cd4f4b8
48b21dc
03704e7
a28629d
03f2878
7bd3d29
a02d587
cc2b82d
0b2219c
b14a806
5d63a7c
d0915dc
7a67e9e
c14787e
ea19e8b
ee047d0
5c6c7a9
f2f4cfe
768b4d2
8a2eb5e
854eca4
82dde04
8f8ae9e
8fb331f
7690c4c
97238c9
a2cc047
a8dff89
b19cd88
d7c6ab9
53aaa7f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
# Overview | ||
This document describes the high-level architecture of *Mir*, including a diagram and a brief introduction of the directory structure. | ||
|
||
# Concepts | ||
## MirAL | ||
- The "Mir Abstraction Layer" (aka `mirAL` or `miral`) is a layer that makes the core Mir implementation easier for compositor-implementers to work with. | ||
mattkae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- If one wishes to implement a compositor themselves, they will spend most of their time interacting with the `mirAL` API and only really touch the `mir` API when they require core concepts like a `mir::geometry::Rectangle`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
## Mir | ||
- The core implementation of the compositor that `MirAL` uses under the hood | ||
- Responsible for doing the heavy-lifting of the compositor, such as: | ||
- Output detection and configuration | ||
- Compositing the image onto outputs | ||
- Implementing the [Wayland protocol](https://wayland.app/protocols/) | ||
- Providing the different platforms that can be used for both display and rendering | ||
- Handling user input and bubbling it up to `MirAL` | ||
- & more! | ||
|
||
# Diagram | ||
![Architecture Diagram](./architecture.png "Architecture Diagram") | ||
|
||
# Code Structure | ||
This section will provide an overview of how the *Mir* codebase is organized through an exploration of the project's directory structure. | ||
|
||
## `/include` | ||
- The `include` folder at the root of the project provides the public-facing API. | ||
- This directory *strictly* includes the interfaces that are useful to a compositor-implementer. | ||
- If one is only interested in implementing their own *Mir*-based compositor, they need not look any further than this directory. | ||
|
||
## `/src` | ||
- The `src` folder at the root of the project comprises the core implementation of *Mir*. | ||
|
||
## `/src/miral` | ||
- Provides an interface to compositor-implementers that abstracts away many of the nitty-gritty details of *Mir*. See [MirAL](#miral) for more details | ||
- Most of the classes in this directory look like this: | ||
|
||
```c++ | ||
class MyClass | ||
{ | ||
public: | ||
void operator()(mir::Server& server) const; | ||
... | ||
}; | ||
``` | ||
Instances of such a class (e.g. `X11Support`) are passed to the `MirRunner::run_with` function, wherein the overloaded operator function is called with the server as a parameter. | ||
|
||
## `/src/server` | ||
- Provides the core *Mir* runtime, with the entry-point being the `mir::Server` class. | ||
- The `Server` class has a `DisplayServer` which provides access to the interfaces that that support the server's runtime. | ||
- The `ServerConfiguration` provides a bunch of methods called `the_XYZ()` to access these various instances, where "XYZ" can be replaced with the interface of interest. | ||
- The classes that the `Server` relies on for its runtime can be found organized in separate folders in this directory. | ||
|
||
## `/src/server/compositor` | ||
- The `Compositor` is responsible for collecting the set of renderables and sending them off to the outputs to be displayed. | ||
|
||
## `/src/server/input` | ||
- This folder deals with everything input (e.g. keyboard presses, mouse clicks) | ||
- The `InputManager` provides access to the specific input platform that is running (e.g. X, Wayland, or libinput). | ||
- The `InputDispatcher` is responsible for taking events bubbled up from the platform and sending them off to the appropriate listeners | ||
|
||
## `/src/server/frontend_wayland` | ||
- The *Mir* implementation of the wayland protocol. | ||
- The `WaylandConnector` class is the glue between the compositor and the specific details of the wayland protocol. | ||
|
||
## `/src/server/frontend_xwayland` | ||
- The *Mir* implementation of the xwayland protocol. | ||
- The `XWaylandConnector` class is the glue between the compositor and the specific details of the xwayland protocol. | ||
- This protocol talks to the `xwayland` server, which is spawned as a subprocess. | ||
|
||
## `/src/server/shell` | ||
- The `Shell` is responsible for managing the surfaces that the compositor wants to show. | ||
- It provides an interface to create, update, and remove these surfaces from the display. | ||
- As an example, the `WaylandConnector` might ask the `Shell` to create a new surface for it. | ||
|
||
## `/src/server/scene` | ||
- The `Scene` provides an interface for the `Compositor` to access the list of renderable items | ||
- These renderables are derived from the surfaces that were added to the `Shell`. | ||
- You can think of the `Scene` as you would think of a "scene graph" in a 3D game engine. | ||
- Unlike the `Shell`, the `Scene` knows a lot about the Z-order of the surfaces. For this reason, it is also responsible for things like locking the display or sending surfaces to the back of the Z-order. | ||
|
||
## `/src/server/graphics` | ||
- A graphics abstraction layer sitting between the compositor and the specific graphics platform that it is using to render. | ||
|
||
## `/src/server/console` | ||
- Handles `logind` and virtual-terminal related tasks for the compositor | ||
|
||
## `/src/server/report` | ||
- Logging and other facilities to collect data about the compositor | ||
|
||
## `/src/platforms` (with an "s"!) | ||
- Provides both input and rendering platforms that the compositor can use depending on the environment. | ||
- For the rendering platforms, we have: | ||
- *GBM/KMS*: the platform that you would expect if you were running a *Mir*-based compositor as your daily-driver | ||
- *X11*: a useful platform for testing locally | ||
- *Wayland*: another useful platform for testing locally | ||
- *EGLStreams/KMS*: like the *GBM/KMS* platform, but for Nvidia | ||
- For the input platforms, we have: | ||
- evdev | ||
- X11 | ||
- Wayland | ||
|
||
## `/src/platform` (no "s") | ||
- Graphics and input code that is shared between platforms | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment: In principle, we aim to make this a public interface for third party "platforms". As Chris has been reworking these APIs, they are currently private |
||
|
||
## `/src/renderers` (with an "s"!) | ||
- The supported `Renderer` types. The renderer is used by the Compositor to build the final image. | ||
- Only GL is supported at the moment. | ||
|
||
## `/src/renderer` (no "s") | ||
- Renderer code that is shared between renderers. | ||
|
||
## `/src/wayland` | ||
- A subproject used to generate C++ classes from wayland protocol XML files. | ||
|
||
## `/src/gl` | ||
- A short list of helpers for GL work. | ||
|
||
## `/src/cookie` | ||
- Provides event timestamps for inputs events that are difficult to spoof. | ||
|
||
## `/src/common` | ||
- A library of common functionality that is used throughout the project, including things like loggers, clocks, executors, etc. | ||
|
||
## `/examples` | ||
- A collection of demo *Mir* compositors that are used as examples of how one might build a true compositor. Examples include: | ||
- `miral-app` | ||
- `miral-shel` | ||
- `mir_demo_server` | ||
|
||
## `/tests` | ||
- Unit tests for the entire project. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
@startuml | ||
|
||
hide members | ||
|
||
' Miral | ||
class miral.MirRunner | ||
class miral.SystemCompositorWindowManager extends mir.shell.WindowManager | ||
class miral.MinimalWindowManager extends miral.WindowManagementPolicy | ||
|
||
miral.MirRunner <-right- mir.Server | ||
miral.MirRunner <-right- miral.SystemCompositorWindowManager | ||
miral.SystemCompositorWindowManager "n" <-d- miral.WindowManagementPolicy | ||
miral.WindowManagementPolicy <- miral.WindowInfo | ||
miral.WindowManagementPolicy <- miral.ApplicationInfo | ||
|
||
|
||
|
||
' Server | ||
class mir.Server | ||
class mir.ServerConfiguration | ||
|
||
' Scene | ||
class mir.scene.SurfaceStack | ||
|
||
' Graphics | ||
class mir.graphics.MultiplexingDisplay extends mir.graphics.Display | ||
abstract class mir.graphics.DisplayPlatform | ||
abstract class mir.graphics.Display | ||
abstract class mir.graphics.DisplayBuffer | ||
class mir.graphics.gbm.Display extends mir.graphics.Display | ||
class mir.graphics.gbm.DisplayBuffer extends mir.graphics.DisplayBuffer | ||
class mir.graphics.wayland.Display extends mir.graphics.Display | ||
class mir.graphics.wayland.DisplayBuffer extends mir.graphics.DisplayBuffer | ||
class mir.graphics.X.Display extends mir.graphics.Display | ||
class mir.graphics.X.DisplayBuffer extends mir.graphics.DisplayBuffer | ||
class mir.graphics.eglstream.Display extends mir.graphics.Display | ||
class mir.graphics.eglstream.DisplayBuffer extends mir.graphics.DisplayBuffer | ||
|
||
' Input | ||
class mir.input.BasicSeat | ||
abstract class mir.input.InputDispatcher | ||
class mir.input.DefaultInputDeviceHub | ||
abstract class mir.input.Platform | ||
class mir.input.evdev.Platform extends mir.input.Platform | ||
class mir.input.wayland.Platform extends mir.input.Platform | ||
class mir.input.X.Platform extends mir.input.Platform | ||
class mir.input.DefaultInputManager | ||
class mir.input.MultiplexingDispatchable | ||
|
||
' Shell | ||
class mir.shell.AbstractShell | ||
class mir.shell.WindowManager | ||
|
||
' Compositor | ||
class mir.compositor.MultithreadedCompositor | ||
class mir.compositor.DefaultDisplayBufferCompositorFactory | ||
|
||
' Renderer | ||
class mir.renderer.RendererFactory | ||
class mir.renderer.Renderer | ||
class mir.renderer.gl.Renderer extends mir.renderer.Renderer | ||
|
||
' Frontends | ||
class mir.frontend.WaylandConnector | ||
class mir.frontend.XWaylandConnector | ||
|
||
' Forces miral on top of mir | ||
miral.MirRunner --[hidden]-> mir.Server | ||
|
||
' Relationships | ||
mir.Server <-right- mir.ServerConfiguration | ||
mir.ServerConfiguration <-- mir.compositor.MultithreadedCompositor | ||
mir.ServerConfiguration <-- mir.input.DefaultInputDeviceHub | ||
mir.ServerConfiguration <-- mir.input.InputDispatcher | ||
mir.ServerConfiguration <-- mir.input.BasicSeat | ||
mir.ServerConfiguration <-- mir.frontend.XWaylandConnector | ||
mir.ServerConfiguration <-- mir.frontend.WaylandConnector | ||
mir.ServerConfiguration <-- mir.graphics.MultiplexingDisplay | ||
mir.ServerConfiguration <-- mir.graphics.DisplayPlatform | ||
mir.ServerConfiguration <-- mir.input.DefaultInputManager | ||
|
||
mir.compositor.MultithreadedCompositor <-- mir.scene.SurfaceStack | ||
mir.compositor.MultithreadedCompositor <-- mir.graphics.MultiplexingDisplay | ||
mir.compositor.MultithreadedCompositor <-- mir.compositor.DefaultDisplayBufferCompositorFactory | ||
mir.compositor.DefaultDisplayBufferCompositorFactory <-- mir.renderer.RendererFactory | ||
|
||
mir.renderer.RendererFactory <-- mir.renderer.Renderer | ||
mir.graphics.MultiplexingDisplay "n" <-right- mir.graphics.Display | ||
mir.graphics.DisplayPlatform <-right- mir.graphics.Display | ||
mir.graphics.Display "n" <-- mir.graphics.DisplayBuffer | ||
mir.graphics.gbm.Display "n" <-- mir.graphics.gbm.DisplayBuffer | ||
mir.graphics.eglstream.Display "n" <-- mir.graphics.eglstream.DisplayBuffer | ||
mir.graphics.X.Display "n" <-- mir.graphics.X.DisplayBuffer | ||
mir.graphics.wayland.Display "n" <-- mir.graphics.wayland.DisplayBuffer | ||
|
||
mir.frontend.WaylandConnector <-- mir.shell.AbstractShell | ||
mir.frontend.XWaylandConnector <-- mir.shell.AbstractShell | ||
mir.shell.AbstractShell <-- mir.scene.SurfaceStack | ||
mir.shell.AbstractShell <-- mir.shell.WindowManager | ||
|
||
mir.input.DefaultInputManager <-- mir.input.Platform | ||
mir.input.DefaultInputManager <-- mir.input.MultiplexingDispatchable | ||
mir.input.BasicSeat <-- mir.input.InputDispatcher | ||
mir.input.DefaultInputDeviceHub <-- mir.input.BasicSeat | ||
mir.input.DefaultInputDeviceHub <-- mir.input.MultiplexingDispatchable | ||
mir.input.Platform <-- mir.input.DefaultInputDeviceHub | ||
mir.input.InputDispatcher <-- mir.shell.AbstractShell | ||
|
||
|
||
package Hardware <<Rectangle>> { | ||
() mouse | ||
() keyboard | ||
() displays | ||
} | ||
|
||
|
||
Hardware.mouse <-- mir.input.evdev | ||
Hardware.keyboard <-- mir.input.evdev | ||
Hardware.displays <-- mir.graphics.Display | ||
|
||
@enduml |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think at this level of abstraction there are more concepts. Basically, what you've called "Mir" breaks into several things:
I think "Mir" ought to be the collective. And, maybe the highest level architecture is enumerating the shared libraries and which are "for consumption" and which are "internal"?