Architecture

This document introduces the architecture of Mir at a high-level.

Audience

This document is intended to provide contributors to Mir an overview of Mir’s systems. It is not intended to guide compositor authors.

APIs for compositor authors

        
classDiagram
    CompositorAuthor --> miral: Uses
    CompositorAuthor --> miroil: Uses
    CompositorAuthor --> mirwayland: Uses

    miral --> mirserver: Uses
    miroil --> mirserver: Uses
    mirwayland --> mirserver: Uses

    note for core "Universal"
    note for common "Universal"
    class core
    class common

    

Mir provides compositor authors with a set of libraries that they can use to build Wayland based shells. These libraries are:

  • miral

  • miroil

  • mirwayland

Miral

The most commonly used library is miral. miral (the “Mir Abstraction Layer”) is an API that makes Mir easy for compositor authors to work with. It provides core window management concepts and an interface that is more ABI stable than Mir’s internal API. While miral is built on the Mir engine, compositor authors are encouraged to only interact with the high-level miral library.

Miroil

miroil is a custom library for the Lomiri folks. It is like miral in that it provides an abstraction over the Mir engine. However, most compositor authors will not interact with miroil.

Mirwayland

Compositor authors may want to define their own wayland protocol extensions in addition to the ones that the core Mir implementation defines. The mirwayland library satisfies this requirement. This library may be used in conjunction with either miral or miroil.

The Mir engine

        
classDiagram
    Compositor --> Scene: Get renderables
    Compositor --> Display: Get outputs
    Compositor --> RenderingPlatform: Handles rendering
    Compositor --> DisplayPlatform: Outputs image to
    Shell --> miral: Get shell behavior
    Shell --> Scene: Updates
    InputDispatcher <-- InputPlatform: Sends events to
    Seat <-- InputDispatcher: Sends events to
    Seat --> Shell: Sends events to
    FrontendWayland --> Shell: Makes requests to
    FrontendXWayland --> Shell: Makes request to
    Scene o-- IdleHub
    Scene o-- Clipboard
    Scene o-- SceneChangeNotifiers


    %%Server --> Core
    %%Server --> Common

    

The mirserver library is the core implementation of Mir. It serves as the engine for both miral and miroil. This library does the heavy-lifting for the compositor and, as a result, is the largest piece of Mir. This section will explain the primary concepts that drive the engine.

Core Concepts

At the heart of mirserver are two interfaces: the Shell and the Scene. The Shell is responsible for fielding requests from the rest system. The Shell modifies the state of the Scene to reflect the requested changes.

For example, the Frontend would ask the Shell to initiate dragging a window. The Shell would then decide how to move that window to and update the state of the Scene to reflect that change.

From Scene to Screen

Knowing that the Scene holds the state of what is to be displayed, we can talk about the Compositor. The Compositor gets the collection of items to render from the Scene, renders them with the help of the rendering platform, and sends them off to the display platform to be displayed.

From Interaction to Shell

As stated previously, the Shell handles requests from the system and updates the state of the Scene accordingly. These requests come from a variety of sources, which we will investigate now.

Frontend Wayland: Responsible for connecting the Wayland protocol with the rest of Mir. The WaylandConnector class connects requests made via the Wayland protocol to the core state of the compositor.

Frontend XWayland: Responsible for connecting requests sent by an XWayland server to the rest of Mir. The XWaylandConnector establishes this connection. This frontend spawns an XWayland server as a subprocess.

Input: Handles everything having to do with input, including mouse, keyboard, touch, and more. This system interacts with the specific input platform and bubbles up events through a list of InputDispatchers, which enables different pieces of the software to react to events.

For example, a compositor’s window manager may respond to a key press event by opening up a new terminal via a request to the Shell.

Platforms

We briefly hinted at the existence of so-called “platforms” previously, but they are deserving of a dedicated section. A Platform is an adapter that allows the system to work across different graphics, input, and rendering stacks. They come in three flavors:

  • Display Platform: Determines what the compositor is rendering to. This may be a physical monitor via GBM/KMS (or EGLStreams for Nvidia), an X11 or Wayland window, or a completely virtual buffer.

  • Input Platform: Determines where the compositor is getting input from. This could be native event via libinput, X input events, or Wayland input events.

  • Rendering Platform: Determines how the compositor renders the final image. For now, only a GL backend is supported.

The GBM/KMS platform is most typically what will be used, as it is the native platform. The X11 platform is useful for development. The Wayland platform is specifically useful for Ubuntu Touch, where they are hosting Mir in another Wayland compositor.

Supporting Libraries

Mir leans on a few core libraries to support the entire system. These libraries contain data structures and utilities that are shared throughout the project, including miral and miroil.

  • Core: Fundamental data concepts, like file descriptors and rectangles. These data structures tend not to be Mir-specific.

  • Common: Mir-specific data concepts like Mir event building, logging, and timing utilities.