SDV Media stellt OEM-Apps mit der Linux DRM API verfügbare Displays zur Verfügung.
Abbildung 1 : Interaktion zwischen DRM-Komponenten
Ein Framebuffer ist eine Quelle für Pixeldaten, die von einem extern zugewiesenen Speicherpuffer unterstützt wird.
Eine Ebene ist eine Bildquelle, die von CRTC verwendet wird. Sie ist mit einem Framebuffer verknüpft und kann eine zugeschnittene Ansicht des Framebuffers darstellen.
CRTC steht für eine allgemeine Display-Pipeline. Sie kann mehrere Ebenen kombinieren, um die endgültige Videoausgabe zu erstellen, und die Ausgabe an mehrere Encoder senden.
Ein Encoder wandelt die Videoausgabe von CRTC in ein Format um, das für einen bestimmten Connector geeignet ist.
Ein Connector stellt einen verfügbaren Display-Connector dar. Beispiel: ein HDMI-Anschluss.
Weitere Informationen finden Sie unter:
API-Oberfläche
SDV Media bietet die Linux DRM-Schnittstellen. Sie können zwar direkt mit dem ioctl-Systemaufruf verwendet werden, für die Anwendungsentwicklung wird jedoch die Verwendung einer Userspace-Hilfsbibliothek empfohlen. Beispiel:
drm-rsCrate für Rust (empfohlen)libdrmfür C/C++.drm-kmsman page bietet einen umfassenden Überblick über die APIs und ihre Verwendung.
Rendering auf einem einzelnen Display einrichten
Öffnen Sie ein DRM-Gerät (
/dev/dri/card*) und verwenden Sie Linux DRM APIs, z. B. überlibdrm, auf dem zugehörigen Dateideskriptor, um das Display und den Modus auszuwählen.Normalerweise stellt das Hostsystem nur ein einzelnes virtuelles GPU-Gerät zur Verfügung, das als
/dev/dri/card0angezeigt wird.Weisen Sie mit der Linux DRM API Front- und Back-Buffer zu.
Wir empfehlen,
minigbm'sgbm_bo_create()zu verwenden und den DMA-BUF-Dateideskriptor mitgbm_bo_get_fd()abzurufen.Erstellen Sie GL-Framebuffer, die von den zugewiesenen Buffern unterstützt werden.
Erstellen Sie mit
eglCreateImageKHRundEGL_LINUX_DMA_BUF_EXT(ausEGL_EXT_image_dma_buf_importErweiterung) einEGLImageaus dem DRM-Buffer.Erstellen Sie eine GL-Textur und legen Sie mit
glEGLImageTargetTexture2DOES(ausGL_OES_EGL_imageErweiterung) den Speicher der Textur auf dasEGLImageaus dem vorherigen Schritt fest.Erstellen Sie einen GL-Framebuffer und legen Sie mit
glFramebufferTexture2Ddie unterstützende Textur auf die im vorherigen Schritt erstellte Textur fest.
So rendern Sie einen Frame:
Binden Sie einen der erstellten GL-Framebuffer.
Zeichnen Sie einen Frame mit den üblichen GLES APIs.
Zeigen Sie den Frame auf einem Bildschirm an: Senden Sie mit der Linux DRM API (
drmModeAtomicCommit()) einDRM_MODE_PAGE_FLIP_EVENTmit dem DMA-BUF-Dateideskriptor, der vom gebundenen GL-Framebuffer verwendet wird.
Videoausgabe aus mehreren Ebenen zusammensetzen
Für die hardwarebeschleunigte mehrschichtige (Multi-Plane-)Komposition muss das Hostsystem jede Ebene als separaten DRM-Connector (virtuelles Display) zur Verfügung stellen und sie dem richtigen Hardwarestandort bzw. der richtigen Pipeline zuordnen.
Weitere Informationen finden Sie unter Rendering auf mehreren Displays einrichten.
Rendering auf mehreren Displays einrichten
Öffnen Sie das DRM-Gerät
/dev/dri/card*wie im Ablauf für ein einzelnes Display.Listen Sie die verfügbaren Display-Connectors auf.
Jedes Display wird als separater DRM-Connector des DRM-Geräts zur Verfügung gestellt.
Für jeden Display-Connector:
Wählen Sie eine CRTC aus, die mit dem Connector kompatibel ist. Jeder Connector hat eine Liste der verfügbaren Encoder und jeder Encoder gibt an, mit welchen CRTCs er verwendet werden kann. Es gibt immer mindestens eine kompatible CRTC.
Wählen Sie eine Ebene aus, die mit der CRTC kompatibel ist.
Erstellen Sie DRM-Framebuffer, die von GPU-Buffern unterstützt werden. Dieser Vorgang ist derselbe wie bei der Variante mit einem einzelnen Display.
Verbinden Sie Ebene, CRTC und Connector und legen Sie den Videomodus auf der CRTC fest.
Sie können den Modus mehrerer Displays gleichzeitig festlegen, indem Sie die Atomic API verwenden, um die folgenden DRM-Attribute für jeden Connector, jede CRTC und jede Ebene festzulegen.
Vollständige Liste der erforderlichen Attribute:
Ziel Attribut Typ Beschreibung Connector CRTC_IDCRTC-ID ID der CRTC, die dem Connector zugewiesen werden soll CRTC MODE_IDBlob-ID ID eines Attribut-Blobs, das mit drmModeCreatePropertyBloberstellt wurde und diedrmModeModeInfo-Struktur des ausgewählten Videomodus enthältCRTC ACTIVEBoolesch true, um die CRTC als aktiv zu markierenEbene FB_IDFramebuffer-ID ID des DRM-Framebuffers, der auf dem Bildschirm angezeigt werden soll Ebene SRC_XPixel X-Koordinate des Quellbildrechtecks des Framebuffers Ebene SRC_YPixel Y-Koordinate des Quellbildrechtecks des Framebuffers Ebene SRC_W16.16-Festpunkt Breite des Quellbildrechtecks des Framebuffers (Pixel um 16 Bit nach links verschoben) Ebene SRC_H16.16-Festpunkt Höhe des Quellbildrechtecks des Framebuffers (Pixel um 16 Bit nach links verschoben) Ebene CRTC_XPixel X-Koordinate des Zielbildrechtecks der CRTC Ebene CRTC_YPixel Y-Koordinate des Zielbildrechtecks der CRTC Ebene CRTC_WPixel Breite des Zielbildrechtecks der CRTC Ebene CRTC_HPixel Höhe des Zielbildrechtecks der CRTC Geben Sie die Rendering-Schleife ein:
Warten Sie auf das Seitenwechselereignis auf einer CRTC, bevor Sie den nächsten Frame rendern.
Rendern Sie einen Frame und zeigen Sie ihn auf dem Bildschirm an, indem Sie einen Seitenwechsel für die angegebene CRTC + den angegebenen Framebuffer planen.