\documentclass[aspectratio=169,obeyspaces,spaces,hyphens,dvipsnames,handout]{beamer}
\usepackage[utf8]{inputenc}
\usepackage{lmodern}% http://ctan.org/pkg/lm
\usepackage{minted}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{pgfplots}
\usepackage{tikz}
\usepackage{stmaryrd}
\usepackage[normalem]{ulem}

\usetikzlibrary[shapes,arrows]

\mode<presentation>
\usetheme{Bootlin}

\def\signed #1{{\leavevmode\unskip\nobreak\hfil\penalty50\hskip2em
  \hbox{}\nobreak\hfil(#1)
  \parfillskip=0pt \finalhyphendemerits=0 \endgraf}}

\newsavebox\mybox
\newenvironment{aquote}[1]
  {\savebox\mybox{#1}\begin{quotation}}
  {\signed{\usebox\mybox}\end{quotation}}

\makeatletter
\newbox\@backgroundblock
\newenvironment{backgroundblock}[2]{%
  \global\setbox\@backgroundblock=\vbox\bgroup%
    \unvbox\@backgroundblock%
    \vbox to0pt\bgroup\vskip#2\hbox to0pt\bgroup\hskip#1\relax%
}{\egroup\egroup\egroup}
\addtobeamertemplate{background}{\box\@backgroundblock}{}
\makeatother

\tikzstyle{block} = [rectangle, draw=blorange, text width=8em, text centered, rounded corners, minimum height=3em]
\tikzstyle{arrow} = [thick,->,>=stealth]

\title{Walking Through the Linux-Based Graphics Stack}
\authors{Paul Kocialkowski}
\email{paul@bootlin.com}
\slidesurl{https://bootlin.com/pub/conferences/}
\institute{Bootlin}
\conference{Embedded Linux Conference Europe 2022}

\begin{document}

\addtocontents{toc}{\protect\setcounter{tocdepth}{-1}}
\section{Walking Through the Linux-Based Graphics Stack}
\addtocontents{toc}{\protect\setcounter{tocdepth}{2}}

\begin{frame}{Paul Kocialkowski}
  \begin{itemize}
  \item Embedded Linux engineer at Bootlin
    \begin{itemize}
    \item Embedded Linux {\bf expertise}
    \item {\bf Development}, consulting and training
    \item Strong open-source focus
    \end{itemize}
  \item Open-source contributor
    \begin{itemize}
    \item Co-maintainer of the \textbf{cedrus} VPU driver in V4L2
    \item Author of the \textbf{ov5648} and \textbf{ov8865} V4L2 camera sensor drivers
    \item Author of the \textbf{logicvc-drm} DRM display controller driver
    \item Contributor to the \textbf{sun4i-drm} DRM display controller driver
    \item Developed the \textbf{displaying and rendering graphics with Linux} training
    \end{itemize}
  \item Living in {\bf Toulouse}, south-west of France
  \end{itemize}
\end{frame}

\begin{frame}{Talk Outline}
  Agenda:
  \begin{itemize}
  \item Big Picture Overview of Graphics
  \item Early Graphics
  \item Graphics on a Running System
  \end{itemize}~\\

  Focus:
  \begin{itemize}
  \item{System-level aspects}
  \item{Shed light on little-known aspects}
  \item{Code references to popular/reference projects}
  \end{itemize}
\end{frame}

\subsection{Big Picture Overview of Graphics}

\begin{frame}[t]{Graphics Hardware: Memory}
  \begin{center}\color{blorange}
  Rationale: where is the graphics data stored, how is it accessed?
  \end{center}

  Graphics data (pixels) storage:
  \begin{itemize}
  \item \textbf{Framebuffers} are the memory areas for pixles
  \item \textbf{Memory location} depends on the situation:
    \begin{itemize}
    \item System memory or dedicated graphics memory
    \item Paged (fragmented) or contiguous memory
    \end{itemize}
  \item Specific formats, modifiers, compression, lack of meta-data
  \end{itemize}\pause~

  Graphics memory access:
  \begin{itemize}
  \item Hardware-side memory access: \textbf{DMA, IOMMU}
  \item System-side memory access: \textbf{bus mapping, cache}
  \end{itemize}
\end{frame}

\begin{frame}[t]{Graphics Hardware: Displaying}
  \begin{center}\color{blorange}
  Rationale: going from memory to photons
  \end{center}

  \begin{itemize}
  \item Pixels mixing: \textbf{planes/layers} (rotation, scaling, format and more)
  \item Timings generation: \textbf{CRTC}
  \item Interface layer: \textbf{encoder} (controller, PHY)
  \item Transcoding: \textbf{bridge}
  \item Surface: \textbf{panel, monitor}, various technologies
  \end{itemize}~

\begin{center}
\begin{tikzpicture}[shorten >=1pt,auto,node distance=8em,semithick, scale=0.5, every node/.style={scale=0.5}]

\node [block] (framebuffer-1) {Framebuffer};
\node [block,dashed] (framebuffer-2) [below of=framebuffer-1, node distance=4em] {Framebuffer};

\node [block] (plane-1) [right of=framebuffer-1, node distance=12em] {Plane};
\node [block,dashed] (plane-2) [below of=plane-1, node distance=4em] {Plane};

\node [block] (crtc) [right of=plane-1, node distance=12em] {CRTC};
\node [block] (encoder) [right of=crtc, node distance=12em] {Encoder};
\node [block,dashed] (bridge) [right of=encoder, node distance=12em] {Bridge};

\node [block] (panel) [right of=bridge, node distance=12em] {Panel / Monitor};

\node (plane-2-right-arrow) [right of=plane-2, node distance=6em] {};
\node (crtc-left-arrow) [left of=crtc, node distance=6em] {};

\draw [arrow] (framebuffer-1) -- (plane-1) node [midway,above=2em] {Memory};
\draw [arrow] (framebuffer-2) -- (plane-2);

\draw [arrow] (plane-1) -- (crtc) node [midway,above=2em] {FIFOs};
\draw [arrow] (crtc) -- (encoder) node [midway,above=2em] {Sync FIFO};
\draw [arrow] (encoder) -- (bridge) node [midway,above=2em] {Display Interface};
\draw [arrow] (bridge) -- (panel) node [midway,above=2em] {Display Interface};

\draw [arrow,-, shorten >= -0.2pt] (plane-2) -- (plane-2-right-arrow.center) -- (crtc-left-arrow.center);

\end{tikzpicture}
\end{center}
\end{frame}

\begin{frame}[t]{Graphics Hardware: Rendering}
  \begin{center}\color{blorange}
  Rationale: generating pixels from primitives
  \end{center}

  \begin{itemize}
  \item \textbf{GPUs} are the all-in-one approach for rendering 3D and 2D
    \begin{itemize}
    \item Vector drawing units exist but are rarely used
    \item Pixels mixers also left out in most cases
    \end{itemize}
  \item Specific hardware features for the task:
    \begin{itemize}
    \item \textbf{Programmable pipeline} with \textbf{shaders}: vertex, geometry, fragment
    \item Dedicated \textbf{vector/SIMD} instruction set(s)
    \item \textbf{Texture mapping units}, cache
    \item \textbf{Tiled framebuffer} representations
    \end{itemize}
  \item Requires a \textbf{dedicated compiler} for shaders
  \item Configured via a \textbf{command stream} in memory
  \item \textbf{High complexity} and power usage
  \end{itemize}
\end{frame}

\begin{frame}[t]{Graphics APIs: Linux kernel}
  \begin{center}\color{blorange}
  Rationale: providing low-level applications access to hardware features
  \end{center}

  Linux kernel subsystms and uAPIs:
  \begin{itemize}
  \item \textbf{Fbdev}: covers display, legacy: missing many many features
  \item \textbf{DRM}: modern subsystem for graphics
    \begin{itemize}
    \item \textbf{KMS}: covers display, up-to-date
    \item \textbf{KMS atomic}: extension for atomic state changes
    \item \textbf{GEM}: memory management, zero-copy (PRIME), fences (Syncobj)
    \item \textbf{Render}: covers rendering, driver-specific
    \end{itemize}
  \end{itemize}~

  Low-level libraries:
  \begin{itemize}
  \item \textbf{libdrm}: wrapper for DRM syscalls
  \end{itemize}
\end{frame}

\begin{frame}[t]{Graphics APIs: Displaying in Userspace}
  \begin{center}\color{blorange}
  Rationale: allowing applications to display their contents
  \end{center}

  Low-level display server APIs:
  \begin{itemize}
  \item \textbf{X11}: legacy protocol with various issues, various extensions
  \item \textbf{Wayland}: modern protocol, various extensions
  \end{itemize}\pause~

  Associated low-level libraries:
  \begin{itemize}
  \item \textbf{Xlib}, \textbf{XCB}: X11 protocol and extensions wrapper
  \item \textbf{libwayland-\{display,server\}}: Wayland protocols marshalling
  \end{itemize}\pause~

  Higher-level graphics libraries/toolkits:
  \begin{itemize}
  \item \textbf{Qt, GTK, EFL}: widget-based toolkits
  \item \textbf{SDL}: drawing-oriented toolkit
  \end{itemize}
\end{frame}

\begin{frame}[t]{Graphics APIs: 2D Rendering in Userspace}
  \begin{center}\color{blorange}
  Rationale: providing high-level access to 2D rendering/operations
  \end{center}

  \begin{minipage}[t]{0.45\linewidth}
  Base drawing libraries:
  \begin{itemize}
  \item \textbf{Cairo}: vector drawing
  \item \textbf{Skia}: vector drawing
  \end{itemize}\pause~

  Pixel-level libraries:
  \begin{itemize}
  \item \textbf{Pixman}: pixel-level operations
  \item \textbf{FFmpeg swscale}: format, scaling
  \item \textbf{G’MIC}: processing
  \end{itemize}
  \end{minipage}
  \begin{minipage}[t]{0.45\linewidth}
  \pause
  Font rendering:
  \begin{itemize}
  \item \textbf{FreeType}: Font rendering
  \item \textbf{Harfbuzz}: Font rendering
  \end{itemize}\pause~

  UI rendering:
  \begin{itemize}
  \item Graphics toolkits
  \item \textbf{ImGui, nuklear}: Immediate-mode
  \end{itemize}
  \end{minipage}
\end{frame}

\begin{frame}[t]{Graphics APIs: 3D Rendering in Userspace}
  \begin{center}\color{blorange}
  Rationale: providing high-level access to 3D rendering
  \end{center}

  \begin{minipage}{0.75\linewidth}
  Standard APIs/formats:
  \begin{itemize}
  \item \textbf{OpenGL (ES)}: Stateful high-level rendering
    \begin{itemize}
    \item \textbf{GLSL}: OpenGL shading language
    \end{itemize}
  \item \textbf{EGL}: Window system integration
    \begin{itemize}
    \item \textbf{GBM}: EGL-DRM KMS glue
    \end{itemize}
  \item \textbf{Vulkan}: Stateless lower-level, low-overhead rendering
    \begin{itemize}
    \item \textbf{SPIR-V}: Intermediate representation for shaders
    \end{itemize}
  \end{itemize}~
  \end{minipage}
  \begin{minipage}{0.2\linewidth}
  \includegraphics[height=2em]{images/opengl-logo.pdf}%
  \vspace{0.5em}
  \includegraphics[height=2em]{images/opengl-es-logo.pdf}%
  \vspace{0.5em}
  \includegraphics[height=2em]{images/egl-logo.pdf}%
  \vspace{0.5em}
  \includegraphics[height=2em]{images/vulkan-logo.pdf}%
  \end{minipage}\pause

  Implementations:
  \begin{itemize}
  \item \textbf{Mesa 3D}: reference free software, using DRM
  \item \textbf{Proprietary}: hardware-specific, various issues
  \end{itemize}
\end{frame}

\begin{frame}{Graphics APIs: Summary Diagram}
\begin{center}
\begin{tikzpicture}[shorten >=1pt,auto,node distance=8em,semithick, scale=0.5, every node/.style={scale=0.5}]

% Userspace

\node (anchor-north) {};
\node (anchor-south) [below of=anchor-north, node distance=16em] {};

\node [block] (applications) [left of=anchor-north, node distance=14em] {Applications};
\node [block] (toolkits) [below of=applications, minimum height=6em] {Toolkits};
\node [block] (display-server)[below of=toolkits] {Display Server};

\node (userspace-center) [above of=anchor-north, node distance=3em] {};
\node (userspace-left) [left of=userspace-center, node distance=30em] {};
\node (userspace-right) [right of=userspace-center, node distance=30em] {};
\node (userspace-text-left) [below of=userspace-left, node distance=2em] {};
\node (userspace-text) [right of=userspace-text-left, node distance=3em] {User space};
\draw [dashed] (userspace-left.center) -- (userspace-right.center);

\node (anchor-north-middle) [below of=anchor-north, node distance=3em] {o};
\node (anchor-middle) [below of=anchor-north, node distance=8em] {o};
\node (anchor-south-middle) [above of=anchor-south, node distance=3em] {o};

\node (anchor-east) [right of=anchor-middle, node distance=14em] {};
\node [block] (2d-rendering) [minimum height=6em, right of=anchor-north-middle, node distance=14em] {2D rendering\\ libraries};

\node [block] (mesa-3d) [minimum height=6em, right of=anchor-south-middle, node distance=14em] {Mesa 3D};

\draw [arrow] (applications) -- (toolkits) node[midway,right] {API};
\draw [arrow] (toolkits) -- (display-server) node[midway,right] {Display protocol};

\draw [arrow,-] (applications) -- (anchor-north.center) -- (anchor-middle.center);
\draw [arrow,-] (toolkits) -- (anchor-middle.center);
\draw [arrow,-] (display-server) -- (anchor-south.center) -- (anchor-middle.center);

\draw [arrow] (anchor-north-middle.center) -- (2d-rendering) node[midway,above] {API};
\draw [arrow] (anchor-south-middle.center) -- (mesa-3d) node[midway,above] {OpenGL, Vulkan} node[midway,below] {EGL};

\draw [arrow] (2d-rendering) -- (mesa-3d) node[midway,right] {OpenGL, Vulkan};

\node (applications-arrow-left) [left of=applications] {};
\node (display-server-arrow-left) [left of=display-server] {};

\draw [arrow,-, shorten >= -0.2pt] (applications) -- (applications-arrow-left.center) -- (display-server-arrow-left.center)  node[midway,left] {Display protocol};
\draw [arrow,->] (display-server-arrow-left.center) -- (display-server);

\pause

% Kernel

\node (kernel-center) [below of=anchor-south, node distance=4em] {};
\node (kernel-left) [left of=kernel-center, node distance=30em] {};
\node (kernel-right) [right of=kernel-center, node distance=30em] {};
\node (kernel-text-left) [below of=kernel-left, node distance=2em] {};
\node (kernel-text) [right of=kernel-text-left, node distance=3em] {Kernel space};
\draw [dashed] (kernel-left.center) -- (kernel-right.center);

\node [block] (drm-kms) [below of=display-server] {DRM KMS};
\node [block] (drm-gem) [right of=drm-kms, node distance=14em] {DRM GEM};
\node [block] (drm-render) [right of=drm-gem, node distance=14em] {DRM Render};

\draw [arrow] (mesa-3d) -- (drm-render) node[midway,right] {Driver uAPI};
\draw [arrow] (display-server.south) -- (drm-kms.north) node[midway,above right] {libdrm};
\draw [arrow] (drm-kms.east) -- (drm-gem.west);
\draw [arrow] (drm-render.west) -- (drm-gem.east);

\pause

% Hardware

\node (hardware-center) [below of=drm-gem, node distance=4em] {};
\node (hardware-left) [left of=hardware-center, node distance=30em] {};
\node (hardware-right) [right of=hardware-center, node distance=30em] {};
\node (hardware-text-left) [below of=hardware-left, node distance=2em] {};
\node (hardware-text) [right of=hardware-text-left, node distance=3em] {Hardware};
\draw [dashed] (hardware-left.center) -- (hardware-right.center);

\node [block] (ram) [below of=drm-gem] {DRAM/VRAM};

\node [block] (display-engine) [below of=drm-kms] {Display Engine};
\node [block] (gpu) [below of=drm-render] {GPU};

\draw [arrow] (drm-kms) -- (display-engine)  node[midway,above right] {Registers};
\draw [arrow] (drm-render) -- (gpu)  node[midway,above right] {Command stream};

\draw [arrow] (drm-gem) -- (ram)  node[midway,above right] {Allocation, mapping};
\draw [arrow] (ram) -- (display-engine) node[midway,below] {DMA};
\draw [arrow,<->] (gpu) -- (ram) node[midway,below] {DMA};
\end{tikzpicture}
\end{center}
\end{frame}

\subsection{Early Graphics}

\begin{frame}[fragile]{Framebuffer Console}
  \begin{itemize}
  \item Why do we need early graphics?
    \begin{itemize}
    \item Show a \textbf{sign of life} before init
    \item \textbf{Kernel and init logs} for debugging
    \item \textbf{LUKS} password entry in initramfs
    \end{itemize}
  \pause
  \item \textbf{fbcon} implements a VT/TTY bridge with graphics:
    \begin{itemize}
    \item \textbf{stdin} is grabbed via the \textbf{input} subsystem
    \item \textbf{stdout} is rendered and displayed via \textbf{fbdev}
    \item Can be used for kernel logs: \verb,console=tty1,
    \item Enabled with \verb,CONFIG_FRAMEBUFFER_CONSOLE,
    \item Can also display a logo: \verb,CONFIG_LOGO,
    \end{itemize}
  \pause
  \item Framebuffer device provided by:
    \begin{itemize}
    \item \textbf{Boot software}: VESA, EFI, device-tree (simple-framebuffer)
    \item \textbf{Dedicated driver}: hardware-specific
    \item \textbf{DRM fb helper}: compatibility layer
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Framebuffer Console: Code Highlights}
  Linux kernel:
  \begin{itemize}
  \item \verb,drivers/video/fbdev/core/fbcon.c,:
    \begin{itemize}
    \item \verb,struct consw fb_con,
    \item \verb,fbcon_set_bitops(),
    \item \verb,fbcon_prepare_logo(),
    \item \verb,do_fbcon_takeover(),
    \item \verb,fbcon_redraw(),
    \item \verb;fbcon_putc();
    \end{itemize}
  \item \verb,drivers/video/fbdev/core/bitblit.c,:
    \begin{itemize}
    \item \verb,bit_putcs(),
    \end{itemize}
  \item \verb,drivers/tty/vt/vt.c,:
    \begin{itemize}
    \item \verb,struct tty_operations con_ops,
    \item \verb,do_update_region(),
    \item \verb,do_take_over_console,
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{DRM FB Helper: Code Highlights}
  Linux kernel:
  \begin{itemize}
  \item \verb,drivers/gpu/drm/drm_fb_helper.c,:
    \begin{itemize}
    \item \verb,struct fb_ops drm_fbdev_fb_ops,
    \item \verb,drm_fbdev_generic_setup,
    \item \verb,drm_fb_helper_generic_probe(),
    \item \verb,__drm_fb_helper_initial_config_and_unlock(),
    \item \verb,drm_fb_helper_single_fb_probe(),
    \item \verb,drm_fb_helper_pan_display,
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}{Bootsplash}
  \begin{itemize}
  \item Users expect a \textbf{waiting screen} rather than logs
  \item Not a kernel-level feature:
    \begin{itemize}
    \item Dedicated applications for the task
    \item Running after init, as root
    \item Typically in the initramfs
    \end{itemize}
  \item Using either \textbf{fbdev} or \textbf{DRM KMS} directly
  \item Often show systemd boot progress
  \item Various implementations exist:
    \begin{itemize}
    \item \textbf{Plymouth}: most advanced, progress, animations, supports DRM KMS and fbdev
    \item \textbf{Psplash}:  from Yocto Project, progress, uses fbdev
    \item \textbf{Fbsplash}: themable, progress, uses fbdev
    \end{itemize}
  \end{itemize}
\end{frame}

\subsection{Running System}

\begin{frame}[fragile]{VT Mode}
  \begin{itemize}
  \item fbcon \textbf{takes over VT} at boot
    \begin{itemize}
    \item As soon as framebuffer is available
    \end{itemize}
  \item \textbf{VT sharing} between fbcon/userspace:
    \begin{itemize}
    \item Access to the display must be \textbf{exclusive}
    \item Privileged operations
    \item Fbcon needs to be detached
    \item Requires active cooperation
    \end{itemize}
  \pause
  \item \textbf{VT modes} reflect the current VT state:
    \begin{itemize}
    \item \verb,KD_TEXT,: fbcon is attached to the VT
    \item \verb,KD_GRAPHICS,: ready for userspace graphics use
    \item \textbf{Switched} upon request with \verb,KDSETMODE, ioctl,\\
    using the TTY fd (controlling terminal or not)
    \end{itemize}
  \item Similar mechanism exists for input
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{VT Switching}
  \begin{itemize}
  \item Multiple VTs/TTYs are \textbf{spawned at boot}:
    \begin{itemize}
    \item A single VT is \textbf{active} at a time (\verb,tty1, at boot)
    \item Switching triggered with: \verb,Ctrl + Alt + F[n],
    \item No userspace intervention for fbcon
    \end{itemize}
  \pause
  \item \textbf{Coordination required} when userspace uses graphics:
    \begin{itemize}
    \item Kernel needs to notify application of VT switching
    \item Signal-based release/acquire handlers registered with \verb,VT_SETMODE, ioctl
    \item Graphics \textbf{resources} need to be \textbf{released/re-acquired}
    \item Kernel waits for acknowledge (can hang)
    \end{itemize}
  \pause
  \item Implications for \textbf{complex systems}:
    \begin{itemize}
    \item Multiple graphics sessions can run in \textbf{parallel}!
    \item Typically the case with the login manager
    \item Other limitations might restrict this ability
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{VT Mode and Switching: Code Highlights}
  \begin{minipage}[t]{0.45\linewidth}
  Linux kernel:
  \begin{itemize}
  \item \verb,drivers/tty/vt/vt_ioctl.c,:
    \begin{itemize}
    \item \verb,vt_k_ioctl(),
    \item \verb,vt_kdsetmode(),
    \item \verb,change_console(),
    \item \verb,complete_change_console(),
    \end{itemize}
  \item \verb,drivers/tty/vt/vt.c,:
    \begin{itemize}
    \item \verb,set_console(),
    \item \verb,console_callback(),
    \end{itemize}
  \end{itemize}
  \end{minipage}
  \begin{minipage}[t]{0.45\linewidth}
  Weston:
  \begin{itemize}
  \item \verb,libweston/weston-launch.c,:
    \begin{itemize}
    \item \verb,setup_tty(),
    \item \verb,handle_signal(),
    \end{itemize}
  \item \verb,libweston/launcher-direct.c,:
    \begin{itemize}
    \item \verb,setup_tty(),
    \item \verb,vt_handler(),
    \end{itemize}
  \end{itemize}
  \end{minipage}
\end{frame}

\begin{frame}[fragile]{Sytemd Logind}
  \begin{itemize}
  \item Configuring graphics (and VT) are \textbf{privileged} operations
    \begin{itemize}
    \item Corresponds to DRM KMS \textbf{master} privilege:\\
    \verb,DRM_IOCTL_SET_MASTER/DRM_IOCTL_DROP_MASTER, on DRM KMS fd
    \item Typically restricted to the \textbf{root} user
    \item Used to require running the display server as root
    \item (Very) problematic \textbf{security implications}
    \end{itemize}
  \pause
  \item \textbf{Systemd} introduced \verb,systemd-logind,:
    \begin{itemize}
    \item Runs as root and opens DRM KMS and VT TTY fds
    \item Provides a \textbf{D-Bus service} for applications (display servers):\\
    \verb,org.freedesktop.login1,
    \item DRM KMS fd is passed over UNIX socket
    \item VT operations are made available as methods
    \item Applications can run as \textbf{regular users}!
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Sytemd Logind: Code Highlights}
  Systemd:
  \begin{itemize}
  \item \verb,src/login/logind-session-device.c,:
    \begin{itemize}
    \item \verb,session_device_open(),
    \end{itemize}
  \item \verb,src/login/logind-session.c,:
    \begin{itemize}
    \item \verb,manager_vt_switch(),
    \end{itemize}
  \item \verb,src/login/logind-session.c,:
    \begin{itemize}
    \item \verb,session_open_vt(),/\verb,session_prepare_vt(),
    \item \verb,session_restore_vt(),/\verb,session_leave_vt(),
    \end{itemize}
  \item \verb,src/login/logind-session-dbus.c,:
    \begin{itemize}
    \item \verb,method_take_device(),/\verb,method_release_device(),
    \end{itemize}
  \end{itemize}

  Weston:
  \begin{itemize}
  \item \verb,libweston/launcher-logind.c,:
    \begin{itemize}
    \item \verb,launcher_logind_take_device(),/\verb,launcher_logind_release_device,
    \item \verb,launcher_logind_activate_vt(),
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[t,fragile]{Login manager}
  \begin{center}\color{blorange}
  Rationale: users needs to login in multi-user/general-purpose setups
  \end{center}

 \begin{itemize}
 \item Login managers provide a \textbf{graphical equivalent} to \verb,getty,
 \item Run their \textbf{own display server} under their own user
 \item Started at the end of the boot process (on first VT)
 \item Allow selecting between different \textbf{sessions}:
   \begin{itemize}
   \item \textbf{X.org}: \verb,/usr/share/xsessions/, desktop files
   \item \textbf{Wayland}: \verb,/usr/share/wayland-sessions/, desktop files
   \end{itemize}
 \item Starts display server in \textbf{user context}:
   \begin{itemize}
   \item Usually authenticated via PAM
   \item Usually in a dedicated VT
   \end{itemize}
 \end{itemize}
\end{frame}

\begin{frame}[t,fragile]{Display Server: Submitting Pixels}
  \begin{center}\color{blorange}
  Rationale: applications want to submit pixels to the display server
  \end{center}

  \begin{itemize}
  \item Actualy \textbf{transfer of pixels} is \textbf{deprecated}:
    \begin{itemize}
    \item \textbf{Zero-copy} buffer sharing with display server is used instead
    \item Buffers are identified by API-specific \textbf{identifiers} (e.g. fds)
    \end{itemize}
  \pause
  \item \textbf{Buffer sharing} has two major instances:
    \begin{itemize}
    \item \textbf{SHM}: Typically drawn by the CPU
    \item \textbf{EGL}: Typically drawn by the GPU
    \end{itemize}
  \item \textbf{Allocation} is often managed by APIs
    \begin{itemize}
     \item Zero-copy import may be possible:\\
     e.g. \verb,EGL_EXT_image_dma_buf_import,
     \item Might cause hardware access issues (but usually works)
    \end{itemize}

  \item \textbf{Coordination} with the display server for presentation:
    \begin{itemize}
    \item Damage region provided by application (e.g. \verb,wl_surface_damage,)
    \item Sync point when ready for presentation (e.g. \verb,wl_surface_commit,)
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Display Server: Submitting Pixels: Code Highlights}
  Weston:
  \begin{itemize}
  \item \verb,clients/simple-damage.c,:
    \begin{itemize}
    \item \verb,create_window(),
    \item \verb,redraw(),
    \end{itemize}
  \item \verb,clients/simple-shm.c,:
    \begin{itemize}
    \item \verb,create_display(),
    \item \verb,redraw(),
    \end{itemize}
  \item \verb,clients/simple-egl.c,:
    \begin{itemize}
    \item \verb,create_surface(),
    \item \verb,init_egl(),
    \item \verb,redraw(),
    \end{itemize}
  \item \verb,clients/simple-dmabuf-egl.c,:
    \begin{itemize}
    \item \verb,create_dmabuf_buffer(),
    \item \verb,redraw(),
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[t]{Display Server: Compositing}
  \begin{center}\color{blorange}
  Rationale: display servers need to gather applications buffers
  \end{center}

  \begin{itemize}
  \item A \textbf{unique buffer} is submitted to the display hardware:
    \begin{itemize}
    \item Contains the contents of all visible applications
    \item Stacked according to window manager policy
    \item Needs to be redrawn upon (visible) application indication
    \end{itemize}
  \pause
  \item Compositing is a \textbf{very demanding} task:
    \begin{itemize}
    \item Full redraw must be avoided at all costs!
    \item Can run up to display frame rate (e.g. 60 Hz)
    \item Damage is tracked and used for clipping regions
    \end{itemize}
  \pause
  \item \textbf{Hardware acceleration} is leveraged (if not necessary):
    \begin{itemize}
    \item Typically renderd with the GPU, buffers as textures
    \item Hardware planes can be leveraged, but usually not (prinary only)
    \item Cursor is typically composited by the hardware with a dedicated plane
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[fragile]{Display Server: Compositing: Code Highlights}
  Weston:
  \begin{itemize}
  \item \verb,libweston/pixman-renderer.c,:
    \begin{itemize}
    \item \verb,pixman_renderer_repaint_output(),
    \item \verb,draw_view(),
    \item \verb,repaint_region(),
    \item \verb,composite_clipped(),
    \end{itemize}
  \item \verb,libweston/renderer-gl/gl-renderer.c,:
    \begin{itemize}
    \item \verb,gl_renderer_repaint_output(),
    \item \verb,draw_view(),
    \item \verb,repaint_region(),
    \item \verb,texture_region(),
    \end{itemize}
  \end{itemize}
\end{frame}

\begin{frame}[t,fragile]{Display Server: Page Flipping}
  \begin{center}\color{blorange}
  Rationale: achieving glitch-free display contents update
  \end{center}

  \begin{itemize}
  \item \textbf{Tearing} is a well-known issue with display sync:
    \begin{itemize}
    \item Display hardware scans out buffer at given address
    \item Scanout happens continuouslty at refresh rate
    \item Display server needs to update the presented contents
    \item Concurrent read (hardware) and write (displays erver) causes a glitch
    \end{itemize}
  \pause
  \item Tearing is resolved with a \textbf{double-buffering} approach:
    \begin{itemize}
    \item Front buffer is shown, back buffer is being prepared
    \item Roles are exchanged at next vertical sync (vblank) point
    \item More buffers can be used but increase latency
    \end{itemize}
  \pause
  \item DRM KMS ensures \textbf{page flipping} happens at vblank:
    \begin{itemize}
    \item Scheduled using \verb,DRM_IOCTL_MODE_PAGE_FLIP, (with target)
    \item Scheduled with atomic commit using \verb,DRM_IOCTL_MODE_ATOMIC,
    \item Can notify userspace (blocking or async event) when done
    \end{itemize}
  \end{itemize}

\end{frame}

\begin{frame}[fragile]{Display Server: Page Flipping: Code Highlights}
  Weston:
  \begin{itemize}
  \item \verb,libweston/backend-drm/kms.c,:
    \begin{itemize}
    \item \verb,drm_output_apply_state_atomic(),
    \item \verb,drm_pending_state_apply_atomic(),
    \item \verb,drm_output_apply_state_legacy(),
    \item \verb,drm_output_set_cursor(),
    \item \verb,atomic_flip_handler()/page_flip_handler(),
    \end{itemize}
  \end{itemize}
\end{frame}

\questionslide

\end{document}
