SDV Media : gérer les écrans

SDV Media expose les écrans disponibles aux applications OEM avec l'API Linux DRM.

Interaction entre les composants DRM

Figure 1. Interaction entre les composants DRM.

  • Un framebuffer est une source de données de pixels, soutenue par une mémoire tampon allouée en externe.

  • Un plan est une source d'image utilisée par CRTC. Il est associé à un framebuffer et peut représenter une vue recadrée de celui-ci.

  • CRTC représente un pipeline d'affichage global. Il peut combiner plusieurs plans pour créer la sortie vidéo finale et la distribuer à plusieurs encodeurs.

  • Un encodeur convertit la sortie vidéo de CRTC dans un format adapté à un connecteur spécifique.

  • Un connecteur représente un connecteur d'affichage disponible. Par exemple, un port HDMI.

Pour une description plus détaillée, consultez les ressources suivantes :

Surface d'API

SDV Media fournit les interfaces Linux DRM. Bien qu'elles puissent être utilisées directement à l'aide de l'appel système ioctl, il est recommandé d'utiliser une bibliothèque d'assistance de l'espace utilisateur pour le développement d'applications. Exemple :

Configurer le rendu sur un seul écran

  1. Ouvrez un appareil DRM (/dev/dri/card*) et utilisez les API Linux DRM, par exemple via libdrm, sur son descripteur de fichier pour sélectionner l'écran et son mode.

    En règle générale, le système hôte n'expose qu'un seul appareil GPU virtuel, qui s'affiche sous la forme /dev/dri/card0.

  2. Allouez des tampons avant et arrière avec l'API Linux DRM.

    Il est recommandé d'utiliser minigbm's gbm_bo_create() et d'obtenir le descripteur de fichier DMA-BUF avec gbm_bo_get_fd().

  3. Créez des framebuffers GL soutenus par les tampons alloués.

    1. Créez un EGLImage à partir du tampon DRM avec eglCreateImageKHR avec EGL_LINUX_DMA_BUF_EXT (à partir de EGL_EXT_image_dma_buf_import extension).

    2. Créez une texture GL et utilisez glEGLImageTargetTexture2DOES (à partir de l'extension GL_OES_EGL_image) pour définir le stockage de la texture sur le EGLImage de l'étape précédente.

    3. Créez un framebuffer GL et utilisez glFramebufferTexture2D pour définir sa texture de sauvegarde sur celle créée à l'étape précédente.

  4. Pour afficher un frame :

    1. Associez l'un des framebuffers GL créés.

    2. Dessinez un frame avec les API GLES habituelles.

    3. Affichez le frame à l'écran : utilisez l'API Linux DRM (drmModeAtomicCommit()) pour envoyer un DRM_MODE_PAGE_FLIP_EVENT avec le descripteur de fichier DMA-BUF utilisé par le framebuffer GL lié.

Composer une sortie vidéo à partir de plusieurs calques

Pour la composition multicouche (multiplan) accélérée par le matériel, nous nous appuyons sur le système hôte qui expose chaque calque en tant que connecteur DRM distinct (affichage virtuel) et qui les mappe à l'emplacement / au pipeline matériel approprié.

Pour en savoir plus, consultez la section Configurer le rendu sur plusieurs écrans.

Configurer le rendu sur plusieurs écrans

  1. Ouvrez l'appareil DRM /dev/dri/card* comme dans le flux d'affichage unique.

  2. Répertoriez les connecteurs d'affichage disponibles.

    Chaque écran est exposé en tant que connecteur DRM distinct de l'appareil DRM.

  3. Pour chaque connecteur d'affichage :

    1. Sélectionnez un CRTC compatible avec le connecteur. Chaque connecteur comporte une liste d'encodeurs disponibles, et chaque encodeur indique les CRTC avec lesquels il peut être utilisé. Il existe toujours au moins un CRTC compatible.

      1. Sélectionnez un plan compatible avec le CRTC.

      2. Créez des framebuffers DRM soutenus par des tampons GPU. Ce processus est identique à celui de la variante à affichage unique.

      3. Connectez le plan, le CRTC et le connecteur, puis définissez le mode vidéo sur le CRTC.

        Il est possible de définir le mode de plusieurs écrans en même temps à l'aide de l'API atomique pour définir les propriétés DRM suivantes pour chaque ensemble de connecteurs, de CRTC et de plans.

    Liste complète des propriétés nécessaires :

    Cible PropriétéTypeDescription
    ConnecteurCRTC_IDID du CRTCID du CRTC à attribuer au connecteur
    CRTCMODE_IDID de blob ID d'un blob de propriété créé à l'aide de drmModeCreatePropertyBlob, contenant la structure drmModeModeInfo du mode vidéo sélectionné
    CRTCACTIVEBooléentrue pour marquer le CRTC comme actif
    PlanFB_IDID du framebufferID du framebuffer DRM à afficher à l'écran
    PlanSRC_XPixelsCoordonnée X du rectangle de l'image source du framebuffer
    PlanSRC_YPixelsCoordonnée Y du rectangle de l'image source du framebuffer
    PlanSRC_WPoint fixe 16.16Largeur du rectangle de l'image source du framebuffer (pixels décalés de 16 bits vers la gauche)
    PlanSRC_HPoint fixe 16.16Hauteur du rectangle de l'image source du framebuffer (pixels décalés de 16 bits vers la gauche)
    PlanCRTC_XPixelsCoordonnée X du rectangle de l'image de destination du CRTC
    PlanCRTC_YPixelsCoordonnée Y du rectangle de l'image de destination du CRTC
    PlanCRTC_WPixelsLargeur du rectangle de l'image de destination du CRTC
    PlanCRTC_HPixelsHauteur du rectangle de l'image de destination du CRTC
  4. Saisissez la boucle de rendu :

    1. Attendez l'événement de retournement de page sur un CRTC avant d'afficher le frame suivant.

    2. Affichez un frame à l'écran en planifiant un retournement de page pour un CRTC+framebuffer donné.